递归:就是在运行过程中调用自己。
构成递归的条件:
a>子问题与原始问题为同样的事,且更为简单;
b>不能无限制的调用自身,必须有一个出口,化简为非递归状况处理。
举个简单的例子:
阶乘, 比如 5! = 5*4*3*2*1 = 120
实现起来就是这样:
int factorial(int n){
if (n == 1)
return 1;
else
return n*factorial(n - 1);
}
函数执行流程如下图所示:
上述内容让我们对递归有了简单的认识和了解
下面让我们来实战两个递归的应用来更进一步的了解递归:
实战1:汉诺塔问题
简述:有A、B、C三个柱子,将A柱子上的n个圆盘借助于B柱子全部移动到C柱子,大圆盘不能放在小圆盘上面。
解:
(1) n==1
第1次 A ---> C 共1次移动
(2) n==2
第1次 A ---> B
第2次 A ---> C
第3次 B ---> C 共3次移动
(3) n==3
第1次 A ---> C
第2次 A ---> B
第3次 C ---> B
第4次 A ---> C
第5次 B ---> A
第6次 B ---> C
第7次 A ---> C 共7次移动
下面我们就看看代码是如何实现的:
void move(int plateNum, char F, char T)
{
cout << F << " ---> " << T << endl;
}
// num:圆盘数量 A B C 分别代表三棵柱子
void hanio(int num, char A, char B, char C)
{
if (num == 1)
move(1, A, C);
else
{
hanio(num - 1, A, C, B);
move(num, A, C);
hanio(num - 1, B, A, C);
}
}
实战2:排列组合问题
求数组 int a[3] = {1, 2, 3}的所有组合方式,并输出。 (结果:123, 132, 213, 231, 312, 321)
简单说明一下思路:
这里我实现了个模板类 Perm.h
#pragma once
#include <iostream>
using namespace std;
template<class T>
void Perm(T list[], int k, int m)
{
int i;
if (k == m)
{
for (i = 0; i <= m; i++)
cout << list[i];
cout << endl;
}
else
{
for (i = k; i <= m; i++)
{
Swap(list[k], list[i]);
Perm(list, k+1, m);
Swap(list[k], list[i]);
}
}
}
template<class T>
inline void Swap(T&a, T&b)
{
T temp = a;
a = b;
b = temp;
}
调用方法:
int _tmain(int argc, _TCHAR* argv[])
{
int list[3] = { 1, 2, 3 };
Perm(list, 0, 2);
return 0;
}