递归算法详解
来源:互联网 发布:grub如何进入linux系统 编辑:程序博客网 时间:2024/05/27 02:30
1.递归:
(1)终止条件 : 如果不满足条件,就不进行递归调用。
(2)一个递归调用语句 : 该递归调用语句的参数应该逐渐逼近不满足条件,以至最后断绝递归。
(3)先测试,后递归调用。
在递归函数定义中,必须先测试,后递归调用。也就是说,递归调用是有条件的,满足了条件后,才可以递归。
步骤:
1. 归纳出“递推”规则
2. 找出“递归结束”的条件,称为递归出口。
#include <iostream>#include<vector>using namespace std;long gcdr(int a,int b){if(a%b==0)return b;return gcdr(b,a%b);}long gcdl(int a,int b){while(b!=0){int temp= a%b; a=b;b= temp;}return a;}int main(int argc, char* argv[]){ cout<<gcdl(72,32); //9 return 0;}
4:各式各样利用递归的问题
1:首先看看那些传统的问题吧,如使用递归来解决斐波那契数列的第n个数是多少?(开始从1开始)
写程序的时候我测试了一下,假如要第100个数字,那我们对比一下不使用的递归的时候时间消耗
- #include <iostream>
- #include <ctime>
- using namespace std;
- int Fib2(int index);
- int Fib1(int index);
- int main(int argc, char* argv[])
- {
- clock_t start,finish;
- cout<<"不使用递归:"<<endl;
- start = clock();
- cout<<"所得结果为 "<<Fib2(40)<<endl;
- finish = clock();
- cout<<"时间消耗为 "<<finish - start<<"毫秒"<<endl;
- cout<<endl;
- cout<<"使用递归:"<<endl;
- start = clock();
- cout<<"所得结果为 "<<Fib1(40)<<endl;
- finish = clock();
- cout<<"时间消耗为 "<<finish - start<<"毫秒"<<endl;
- system("pause");
- return 0;
- }
- int Fib1(int index)
- {
- if(index==1 || index==2)
- return index;
- else
- return Fib1(index-1) + Fib1(index-2); //开始递归调用
- }
- int Fib2(int index)
- {
- if(index == 1 || index ==2)
- return index;
- int *array = new int [index+1];
- array[1]=1; //第0个元素没有使用
- array[2]=2;
- for(int i=3;i<=index;++i)
- array[i] = array[i-1] + array[i-2];
- return array[index];
- }
运行结果:
结果显而易见,差距太明显,在这里我们同时求第40个斐波那契数字比较时间消耗,所以大家可以看到递归的时间消耗是非常严重,在可以不用递归的时候尽量不用,有很多题用一般的思路是很难解的,或者是过程繁琐,如果适当的利用递归,结果将事半功倍!!!
2:递归的汉诺塔
这个程序以及说明在分治算法那一节已经说了,递归和分治通常都是结合在一起使用的,一次次的缩小范围,而且子问题和原问题具有相同的结构!
- #include <stdio.h>
- #include <stdlib.h>
- static int count = -1;
- void move(char x,char y); // 对move函数的声明
- void hanoi(int n,char one,char two,char three) ;// 对hanoi函数的声明\
- int main()
- {
- int m;
- printf("请输入一共有多少个板子需要移动:");
- scanf("%d",&m);
- printf("以下是%d个板子的移动方案:\n",m);
- hanoi(m,'A','B','C');
- system("pause");
- return 0;
- }
- void hanoi(int n,char one,char two,char three) // 定义hanoi函数
- // 将n个盘从one座借助two座,移到three座
- {
- if(n==1)
- move(one,three);
- else
- {
- hanoi(n-1,one,three,two); //首先把n-1个从one移动到two
- move(one,three); //然后把最后一个n从one移动到three
- hanoi(n-1,two,one,three); //最后再把n-1个从two移动到three
- }
- }
- void move(char x,char y) // 定义move函数
- {
- count++;
- if( !(count%5) )
- printf("\n");
- printf("%c移动至%c ",x,y);
- }
3:整数的划分问题
将一个整数分解为若干个整数之和的形式,比如 n = n1+n2+n3+n4··········!不同划分的个数称为N的划分数。
例如对于6而言:
6;
5+1;
4+2,4+1+1;
3+3;3+2+1;3+1+1+1;
2+2+2;2+2+1+1;2+1+1+1+1;
1+1+1+1+1+1 一共有6种!
1、 q(n,1) = 1 ,n>=1 ;
当最大加数不大于1时,任何正整数n只有一种表示方式:n = 1+1+……+1 。n个1的和。
2、q( n,m ) = q( n,n ),n<=m; 最大加数不能大于n。
3、 q( n,n ) = 1 + q( n , n-1 ); 正整数的划分由n1=n和n1<=n的划分组成。
4、q( n,m ) = q( n,m-1 )+q( n-m,m ), n>m>1;正整数n的最大加数不大于m的划分由 n1=m的划分和n1<m的划分组成。
现在可以依据这个递推原理写出程序:
- #include <stdio.h>
- #include <stdlib.h>
- int intPart( int n , int m ) ;
- int main()
- {
- int num ;
- int partNum = 0 ;
- printf("Please input an integer:/n") ;
- scanf("%d",&num) ;
- partNum = intPart(num,num);
- printf("%d/n",partNum) ;
- system("pause");
- return 0;
- }
- int intPart( int n , int m )
- {
- if( ( n < 1 ) ||( m < 1 ) ) return 0 ;
- if( ( n == 1 )||( m == 1 ) ) return 1 ;
- if( n < m ) return intPart( n , n ) ;
- if( n == m ) return intPart( n , m-1 ) + 1 ;
- return intPart( n , m-1 ) + intPart( n - m , m ) ;
- }
4. 整数的全排列问题:
全排列的递归实现也就是不停的交换两个数的位置.
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- void swap(char *a,char *b)
- {
- char temp = *a;
- *a = *b;
- *b = temp;
- }
- //k表示循环到第几个字符,m表示该次循环的总长度
- void arrange(char *pizstr,int k,int m)
- {
- if(k == m)
- {
- static int m_count = 1;
- printf("the %d time:%s\n",m_count++,pizstr);
- }
- else
- {
- for(int i=k;i<=m;i++) //主要递归球全排列的代码
- {
- swap(pizstr+k,pizstr+i);
- arrange(pizstr,k+1,m);
- swap(pizstr+k,pizstr+i);
- }
- }
- }
- void foo(char *p_str)
- {
- arrange(p_str,0,strlen(p_str)-1);
- }
- int main()
- {
- char pstr[] = "12345";
- printf("%s\n",pstr);
- foo(pstr);
- system("pause");
- return 0;
- }
- 递归算法详解-
- 递归算法详解
- 递归算法详解
- 递归算法详解
- 递归算法详解
- 递归算法详解
- 递归算法详解
- 递归算法详解
- C#递归算法详解
- 递归算法详解
- C#递归算法详解
- 递归算法详解
- 全排列递归算法详解
- 25_递归算法详解
- C#算法—递归详解
- 经典算法详解 之 递归算法
- Fibonacci数列的递归与非递归实现算法详解
- 二叉树中序遍历非递归算法详解
- 【互推365】微信公众账号制作团队对内招新了~~~
- 让Eclipse识别MyEclipse的Web项目
- Java_Java EE_轻量_Ant 生成文件(build.xml);
- 易订宝 移动营销网络订货平台
- Redis源码分析(十一)--- memtest内存检测
- 递归算法详解
- C语言经常出现的错误提示
- 我所理解的syslog
- BZOJ 1004 HNOI2008 Cards Burnside引理
- ubuntu14.04安装python爬虫框架Scrapy
- How Tomcat Works读书笔记三-------连接器
- OS X Yosemite最值得升级的六个新特性
- 分支结构总结
- Spring定时器