递归的几种类型

原文:https://blog.csdn.net/qq_34039315/article/details/78679029

1、阶乘

递归思想:n! = n * (n-1)! (直接看公式吧)

首先分析数列的递归表达式: 

int f(int n)
{
	if(n<=1) return 1;
	else return n*f(n-1);
}

2、斐波那契数列

斐波那契数列的排列是:0,1,1,2,3,5,8,13,21,34,55,89,144……依次类推下去,你会发现,它后一个数等于前面两个数的和。在这个数列中的数字,就被称为斐波那契数。

递归思想:一个数等于前两个数的和。(这并不是废话,这是执行思路)

首先分析数列的递归表达式: 

int f(n)
{
	if(n<=1) return 1;
	else return f(n-1)+f(n-2);
}

3、倒序输出一个正整数

例如给出正整数 n=12345,希望以各位数的逆序形式输出,即输出54321。

递归思想:首先输出这个数的个位数,然后再输出前面数字的个位数,直到之前没数字。

 首先分析数列的递归表达式:

写法一:

#include<iostream>
using namespace std;

void f(int n)
{
	if(n/10==0) cout<<n;
	else
	{
		cout<<n%10;
		f(n/10);			
	}	
}

int main()
{
	f(12345);
	return 0;	
}

写法二: 

#include<iostream>
using namespace std;
void f(int n)
{
	cout<<n%10;
	if(n/10)
	{
		f(n/10);
	}
}

int main()
{
	f(12345);
	return 0;
}

4、汉诺塔问题

有n个盘子,3个柱子x,y,z。

1、欲将x柱子上的n个盘子,全部移动到z柱子上;
2、大盘子不能压到小盘子上面。

递归思想: 
1. 将x柱子上的n-1个盘子都移到空闲的y柱子上,并且满足上面的所有条件;
2. 将x杆上的第n个盘子移到z柱子上;
3. 剩下问题就是将y柱子上的n-1个盘子移动到z柱子上了。

公式描述有点麻烦,用语言描述下吧: 
1. 以z柱子为中介,将前n-1个盘子从x柱子挪到y柱子上(本身就是一个n-1的汉诺塔问题了!) ;
2. 将第n个圆盘移动到z柱子上; 
3. 以x柱子为中介,将y柱子上的n-1个盘子移到z柱子上(本身就是一个n-1的汉诺塔问题了!)。
 

#include<iostream>
using namespace std;

void hanoi(int n,char x,char y,char z) //从x柱子,借助y柱子,移动到z柱子 
{
	if(n==0) return;
	else
	{
		hanoi(n-1,x,z,y);   //分治思想,将n-1个盘子看作一个整体
		cout<<"将"<<n<<"号盘子,"<<"从"<<x<<"柱子,移动到"<<z<<"柱子"<<endl;
		hanoi(n-1,y,x,z);		
	}		
} 

int main()
{
	hanoi(5,'A','B','C');
	
	return 0;	
} 

参考:https://blog.csdn.net/qq_41705423/article/details/82025409 

5、排列问题

https://blog.csdn.net/wzy_1988/article/details/8939140

https://blog.csdn.net/Hackbuteer1/article/details/7462447

输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。

递归思想: 
假如针对abc的排列,可以分成 (1)、以a开头,加上bc的排列; (2)、以b开头,加上ac的排列; (3)、以c开头,加上ab的排列。

#include<iostream>
using namespace std;

void permutation(int a[],int k,int n) //k:当前欲固定第k号数据;n:一共有n个数据 
{
	if(k==n-1)  //递归结束条件:选取到第n-1号数据(最后一个数据) 
	{
		for(int i=0;i<n;i++)
		{
			cout<<a[i];
		}
		cout<<endl;
	}
	else
	{
		for(int i=k;i<n;i++)  //轮流当第k号元素 
		{
			swap(a[i],a[k]);  //经过这一步,第k号数据固定下来了 
			permutation(a,k+1,n);  //然后处理后面的数据 
			swap(a[i],a[k]);  //保证下一次循环时,依然是最初的次序 
		}		
	}	
} 

int main()
{
	int a[3]={1,2,3};
	permutation(a,0,3);	
	return 0;
} 

【法二】 

算法笔记 P115

#include<iostream>
using namespace std;
const int maxn=11;

int n,P[maxn],hashTable[maxn]={false};

void generateP(int index)
{
	if(index==n+1) //递归结束条件,已经处理完1号~n号元素
	{
		for(int i=1;i<=n;i++) //从1号开始存储元素,一共n个
		{
			cout<<P[i];
		} 
		cout<<endl;
	}
	for(int x=1;x<=n;x++)
	{
		if(hashTable[x]==false) 
		{
			P[index]=x;
			hashTable[x]=true;
			generateP(index+1);
			hashTable[x]=false;
		}
	}
}
int main()
{
	n=3;
	generateP(1);
	return 0;
}
发布了146 篇原创文章 · 获赞 60 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/OpenStack_/article/details/103707236