前言:
使用递归时,往往问题的解是由子问题层层嵌套,相互联系的;
- 从 前直觉的引导下,应要用递归来解决此类问题。这里要提出的一点是,学习的前期只靠直觉来写代码是经不起推敲的,或者是很难经过简单的几次调试运行出正确的结果。我们要运用数理逻辑和运算规律来解决实际性的问题。即,在递归逻辑可行且递归式存在的前提下,运用递归的方法来处理问题;而不是来直接利用 由做题的积累形成的必要不充分的经验 来处理问题。在这里,也建议大家充分地利用权威的算法设计书本或是通过其他接受知识的途径来形成对于问题处理的本质性的理解,从而在此前提下,不断地丰富对于本质和题目的理解,以达到事半功倍的效果。
回归正题: 古老的汉诺塔
先了解一下这个问题;这个问题要求给出问题的解的过程,以及最后问题的解决所经历的总的操作次数。
要定义一个递归函数表示出问题解决的过程,那么这个递归函数将包含将圆盘从当前位置移动到目标位置的所有步骤。亲切地,称其作“形式型的递归逻辑”。
- 将前n-1个圆盘从起始位置移动到辅助位置,通过目标位置作为中转;
- 将前n-1个圆盘从辅助位置移动到目标位置,通过起始位置作为中转;
- 在函数中引入最小问题的解:将第n个圆盘从起始位置移动到目标位置。
对于表示总的次数,需再声明一个整型变量,在每次递归调用时,执行递加的操作。
则有代码如下:
#include<iostream>
using namespace std;
int counts = 0; // 执行操作的次数
void Hanio(int n,char start,char temp,char end);
/*
n:盘子的个数; start, temp, end:起始位置 辅助位置 目标位置
*/
int main()
{
int n; //输入盘子的个数
cin>>n;
Hanio(n,'A','B','C');
cout<<counts;
return 0;
}
void Hanio(int n,char start,char temp,char end)
{
counts++;
if(n == 1) // 最小问题的解:将第n个圆盘从起始位置移动到目标位置;
{
cout<<start<<"-->"<<end <<endl;
}
else
{
Hanio(n-1,start,end,temp);
cout<<start<<"-->"<<end <<endl;
Hanio(n-1,temp,start,end);
}
}
回归正题: 双汉诺塔问题
数理型的递推式便不再说明;是基于最小问题F(1) = 2;F(n) =2*(F(n-1)+1)的递推式来写出代码的。这里选用了python语言来解决问题,相对于C++的处理方便简洁明了。
则有代码如下:
# f(1) = 2
# f(n) = 2*(f(n-1) + 1)
# 通项如上
def hann(n):
if n == 1:
return 2
else:
f = 2*(hann(n-1)+1)
return f
a = int(input())
print(hann(a))
总结:没有总结。
谢谢您观看到此;祝生活常新