/*--------------------------- 该段为引用-----------
递归算法解决问题的特点:
(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
------------------------------------------------- */
说一下我对递归算法的理解。
递归算法的代码,可以分成两个部分:递归出口(满足输出条件之类的)和递归部分(递归代码的主体)。
递归算法特点之一就是把整体换成部分。比如阶乘和全排列问题,都是把问题“降阶”(待会看代码就知道什么意思了。)
还有一个最重要的特点————————效率低,但是递归算法作为入门级算法还是很值得我这样的小白研究的。
来看看几个经典的问题。1.全排列 ,2.汉诺塔,3.阶乘
1.全排列:给你一个数组,你把这个数组里的数的所有排列方式写列出来。
input {1,2,3}
output{1,2,3},{1,3,2},{2,3,1}......(懒得敲了)
代码:
#include <iostream>
using namespace std;
int n = 0;
void swap(char *q ,char *p)
{ //交换函数
int temp;
temp= *q;
*q = *p;
*p = temp;
}
void perm(char arr[],int k, int m )
{
int i;
if(k >m)
{
for(i = 0 ; i <= m ; i++)
{ //递归结束出口,当数列只剩下一个数的时候输出
cout<<arr[i]<<" ";
}
cout<<endl;
}
else
{
for(i = k ; i <=m;i++)
{ //递归部分
swap(arr[k],arr[i]);
perm(arr,k+1,m);
/*把数组看成1{234}+2{134}+3{124}+4{123}
再把{234}看成2{34}+3{24}+4{23}
一直把整体化为部分,一直把大问题分解成小问题。*/
swap(arr[k],arr[i]);
}
}
}
int main()
{
char arr[] ="1234";
perm(arr,0,3);
return 0;
}
2.汉诺塔问题
就是移环子的游戏
这个也可以用递归算法实现。
ABC分别是123柱子,代码思路大概是这样的
把N-1层的环子先通过C移到B,最后再把第N层的最大的环子移到C,这个时候就剩下一个N-1层的新“塔”,那么我们把他看成一个新的“塔”把B柱看成之前的A柱,通过C柱把(N-1)-1层移到A柱,再把第N-1层的最大(原本第二大)的环子放到C,如此循环最后N=1 就了解了。
#include<iostream>
using namespace std;
void hanoi(int n,char a,char b,char c)
{
if(n==1)
cout<<n<<" "<<a<<" "<<c<<endl;
else
{
hanoi(n-1,a,c,b);
cout<<n<<" "<<a<<" "<<c<<endl;
hanoi(n-1,b,a,c);
}
}
int main()
{
int n;
cout<<"输入正整数:"<<endl;
cin>>n;
cout<<"结果为"<<endl;
hanoi(n,'A','B','C');
/*
假设有4层,跟全排列差不多的想法,先把他看成3层,再看成2层,而且移动的方法是相同的。*/
return 0;
}
3.阶乘……不讲了。。