1 汉诺塔问题简介
1.A柱子上有n个方块;
2.方块由下至上,从大到小;
3.移动方块时,只能将小的方块放在大的方块上;
4.最终将A上所有方块移到C柱子上;
2 问题解决关键
2.1 递归层次
本次打算使用递归实现汉诺塔,那么需要注意递归的关键问题,结束条件与递归的接口,因为不是循环,所以考虑太多节点明显就是没事找事了,所以我们只需要找到每次操作后面的简单规律,然后创造一个通用的递归结构即可。
2.3 汉诺塔的规律
先找规律,从一个方块,再到两个,三个方块;
3 规律寻找
3.1 一个方块
那肯定就是从A-->C了;
3.2 两个方块
第一个方块A-->B,第二个方块A-->C,再将第一个方块B-->C;(有的大佬在这里就发现规律了。。。)
3.3 三个方块
A-->B,A-->B,C-->B,A-->C,B-->A,B-->C,A-->C
(作者比较笨,说实话还没看出来。。。但咱同学都说看出来了,也就不好意思献丑了)
可以发现除了只有一个方块情况,n为其他的块数时,都会经历一个阶段:
都会先把1~n-1块先堆在其中一个柱子上,再把第n块放到目标柱子上
3.4普遍规律
这就出来了,如果每次操作一定会经历这个阶段时,一定可以将其设计为递归结构,但现在问题是,这里只是将其化为三步,一步是1~n-1块转到B柱子上,一步是A~C,一步是B上所有转移到C柱子上,但是如何将(1~n-1块转到B柱子上)与(B上所有转移到C柱子上)这两步设计成递归呢?
其实这个时候我们没有必要再纠结A,B,C三个柱子了,给他们换一个名字,起始柱,中转柱,与目标柱
对于(1~n-1块转到B柱子上)
可以把B柱看做目标柱,A柱为起始柱,问题就变为:
1.起始柱上有n-1个方块;
2.方块由下至上,从大到小;
3.移动方块时,只能将小的方块放在大的方块上;
4.最终将起始柱上所有方块移到目标柱子上;
这段话是不是同样可以套用在(B上所有转移到C柱子上)这一步骤上?
只不过目标柱变成了C,起始柱就变成了B
4 递归结构实现
有了普遍规律,那么就可以做到两点
1.初步递归结构实现;
2.结束条件实现;
明显递归结构由三部分铸成,下面是初步草稿
fun(A->B)
A->C
fun(B->C)
//注意这里的A,B,C只是举例一种情况而已
结束条件也很明显
就是当n-1为零时就再也拆不出来方块了
if (n == 1)
{
printf("%c-->%c\n", qz, mz);
return;
}
//qz为起始柱,mz为目标柱
这时候可以实现递归的完整结构实现了
void hanluota(char qz, char mz, char zz,int n)
{
if (n == 1)
{
printf("%c-->%c\n", qz, mz);
return;
}
hanluota(qz, zz, mz, n - 1);
printf("%c-->%c\n", qz, mz);
hanluota(zz, mz,qz, n - 1);
}
当n=3时,结果如下
汉诺塔问题至此实现, 作者总感觉自己的描述get不到点,但是希望能给大家点启发,不像作者一样直到数据结构时才想清楚,欢迎大家批评指正。