汉诺塔的起源:汉诺塔(也称河内塔)是有法国数学家爱德华·卢卡斯于1883年发明的一道智力题。它源于印度的一个古老传说:大梵天创造世界的时候做了三根钻石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令一组牧师把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。据说牧师们夜以继日地工作,当他们完成任务时,那座塔就将坍塌,世界也将毁灭。
代码如下:
#include <stdio.h>
/**
* Hanoi.
*/
void hanoi(int paraN, char paraSource, char paraDestination, char paraTransit){
if (paraN <=0){
return;
} else {
hanoi(paraN - 1, paraSource, paraTransit, paraDestination);
printf("%c -> %c\r\n", paraSource, paraDestination);
hanoi(paraN - 1, paraTransit, paraDestination, paraSource);
}// of if
}// of hanoi
/**
*test
*/
void hanoiTest() {
printf("--- addToTest begins. ---\r\n");
printf("2 plates\r\n");
hanoi(2, 'A', 'B', 'C');
printf("3 plates\r\n");
hanoi(3, 'A', 'B', 'C');
printf("--- adTest ends. ---\r\n");
}// of addTest
/**
the entrance
*/
int main() {
hanoiTest();
} // of main
运行结果:
学习总结:汉诺塔问题主要运用的是函数递归的思想。汉诺塔问题是一个优秀的递归算法示例,可以帮助我们加深对递归算法的理解。同时,在实际编程时,也可以借鉴类似的递归思路,解决其他复杂的问题。并且在汉诺塔问题中,我们可以通过递归三步来解决问题。这种方法看似简单,但却能够从最基础的情况出发,一步步缩小问题的规模,直到最终得到答案。这种思路的精髓在于将复杂的问题转化为简单的子问题,以提高问题求解的效率,并减少编程难度。
一,自顶向下,逐渐求精。
这种思想就是先专注与高层的设计在慢慢深入。汉诺塔问题就是先考虑将n-1个盘子移动为了完成这个目的我们先移动n-2个盘子以此类推。
二,函数调用、递归和分治。
在解决汉诺塔问题中我们在函数中调用函数来解决问题,这就是递归思想的一种体现。
三,不要跨层分析
就比如我们在分析n个盘子时移动n-1个,就不需要去管n-1个盘子中是怎么移动的。
四,形参和实参。
形参就是定义函数中的参数。实参就是调用函数中的参数。
void hanoi(int paraN, char paraSource, char paraDestination, char paraTransit)
其中的三个参数就是形参。
hanoi(2, 'A', 'B', 'C');
其中三个参数就是实参。
五,有意义,规范的标识符。
在写程序的过程中用有意义,规范的标识符可以便于后期对代码的维护和理解。
六,时间复杂度。
时间复杂度是判断一个算法的好坏。汉诺塔的时间复杂度是用递归的方法求出。
七,递归栈
就是跟踪代码画出树状图就可以知道栈空间中弹出弹入的情况。
八,空间复杂度。
汉诺塔的空间复杂度o(n)。
总结:通过分析闵帆老师对汉诺塔问题提出的几个思路和办法,对自己分析程序问题有了一定的帮助。