递归算法实例
阶乘、斐波那契数列、组合数、排列数、全排列、整数划分、汉诺塔问题
递归思想:
直接或者间接调用自身的算法成为递归算法;
每个递归函数都必须有非递归定义的初始值,下面为递归定义式,否则递归函数无法计算。
求阶乘:
输入:10
输出:3628800
#include<bits/stdc++.h>
using namespace std;
int factorial(int n){ //函数实现求阶乘的功能
if(n==0) return 1; //非递归定义的边界条件,当n=0时,返回结果为1
return n*factorial(n-1); //递归定义式,返回n×factorial;
}
int main(){
int num;
cin>>num;
cout<<"阶乘的结果为"<<factorial(num);
return 0;
}
//if判断的语句,判断条件可以是n=0或者n<=1;
求斐波那契数列:
输入:7
输出:13
#include<bits/stdc++.h>
using namespace std;
int Fibonzcci(int n){ //函数实现求斐波那契的功能
if(n==1||n==2) return 1; //非递归定义的边界条件,当前两项时,返回结果为1
return Fibonzcci(n-1)+Fibonzcci(n-2); //递归定义式,返回Fibonzcci(n-1)+Fibonzcci(n-2);
}
int main(){
int num;
cin>>num;
cout<<"斐波那契的结果为"<<Fibonzcci(num);
return 0;
}
//if判断的语句,判断条件可以是n<=2;
求组合数:
输入:4 2
输出:6
记住公式:C(n,m) = C(n-1,m) + C(n-1,m-1)
#include<bits/stdc++.h>
using namespace std;
//分析:从n个人里选k个人的组合数
//从(n-1)个人里选k个人的组合数+从(n-1)个人里选(k-1)个人的组合数。
int fun(int n, int k) //记住公式:C(n,m) = C(n-1,m) + C(n-1,m-1)
{
if(k > n)
return 0;
else if(k == n||k == 0)
return 1;
else
return fun(n-1,k) + fun(n-1, k-1);
}
int main()
{
int n, k;
cout<<"输入组合的两个数:";
cin>>n>>k;
cout<<"C"<<n<<" "<<k<<": "<<fun(n,k);
}
求排列数:
输入:4 2
输出:12
记住公式:A(n,m) = A(n-1,m) + m*A(n-1,m-1)
#include<bits/stdc++.h>
using namespace std;
//分析:从n个人里选k个人的排列数
//从(n-1)个人里选k个人的排列数+从(n-1)个人里选(k-1)个人的排列数*k。
int fun(int n, int k) //记住公式:A(n,m) = A(n-1,m) + m*A(n-1,m-1)
{
if(k > n)
return 0;
else if(k == 0)
return 1;
else
return fun(n-1,k) + k*fun(n-1, k-1);
}
int main()
{
int n, k;
cout<<"输入排列的两个数:";
cin>>n>>k;
cout<<"A"<<n<<" "<<k<<": "<<fun(n,k);
}
求全排列:
输入:1 2 3
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
3 1 2
#include<bits/stdc++.h>
using namespace std;
void perm(vector<string>b,int k,int m){
if(k==m){ //当k=m时,即k已经走到最后一个,此时可进行输出
for(int i=0;i<=m-1;i++)
cout<<b[i];
cout<<endl;
}
else{
for(int i=k;i<=m-1;i++){ //从当前位置开始,依次交换当前元素与后面的各元素
swap(b[k],b[i]);
perm(b,k+1,m); //递归产生相应的排列
swap(b[k],b[i]); //将原先交换的元素换回来,重新进行下一轮交换
}
}
}
int main(){
string num;
vector<string>a;
while(cin>>num){ //while循环输入排列数据
a.push_back(num);
if(cin.get()=='\n') break;
}
perm(a,0,a.size()); //调用perm方法进行求解全排列
return 0;
}
求整数的最大划分数:
输入:6 6
输出:11
#include<bits/stdc++.h>
using namespace std;
int huafen(int num,int k){
if(num<1||k<1) return 0; //当两数都小于1时,无法进行划分,返回0
if(num==1||k==1) return 1; //当两数都为1时,划分数只能为1
if(num<k) return huafen(num,num); //当最大加数大于划分数时,只能将最大加数变为划分数
if(num==k) return huafen(num,num-1)+1; //当最大加数等于划分数时,最大加数减一,划分总数加一
return huafen(num,k-1)+huafen(num-k,k); //在正常情况下见下图
}
int main(){
int num,k;
cin>>num>>k;
huafen(num,k);
cout<<num<<"最大划分整数不超过"<<k<<"的化分数为"<<huafen(num,k);
}
//6
//5+1
//4+2 4+1+1 q(6,4)=q(6,3)+q(2,4)
//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
求汉诺塔:
输入:3(盘子的个数)
输出:
a->b
a->c
b->c
a->b
c->a
c->b
a->b
#include<bits/stdc++.h>
using namespace std;
void move(int n,char a,char b,char c){
if(n>0){
move(n-1,a,c,b); //把a的n-1个盘子移至c借助b
cout<<a<<"->"<<b<<endl; //把a的最后1个盘(最大的盘)移动到b
move(n-1,c,b,a); //把c上的盘子移至b借助a
}
}
int main(){
int n;
cout<<"请输入要移动的块数:";
cin>>n;
move(n,'a','b','c');
return 0;
}