Hanoi问题代码(含测试和说明)
#include "stdafx.h"
/**
* Hanoi.
*/
void hanoi(int paraN, char paraSource, char paraDestination, char paraTransit) {
if (paraN == 1) {
printf("当前在执行 %c -%d-> %c 的全部转移,出发地址:%d,目标地址:%d, 过渡地址:%d \r\n\t 此时直接移动:%c -> %c \r\n", paraSource ,paraN ,paraDestination, ¶Source, ¶Destination, ¶Transit, paraSource, paraDestination);
} else {
printf("当前在执行 %c -%d-> %c 的初始转移, 出发地址:%d,目标地址:%d, 过渡地址:%d \r\n", paraSource ,paraN ,paraDestination, ¶Source, ¶Destination, ¶Transit);
hanoi(paraN - 1, paraSource, paraTransit, paraDestination);
printf("当前在执行 %c -%d-> %c 的中间转移,没有调用hanoi函数 \r\n\t 此时直接移动:%c -> %c \r\n",paraSource ,paraN ,paraDestination, paraSource, paraDestination);
printf("当前在执行 %c -%d-> %c 的最终转移, 出发地址:%d,目标地址:%d, 过渡地址:%d \r\n", paraSource ,paraN ,paraDestination, ¶Source, ¶Destination, ¶Transit);
hanoi(paraN - 1, paraTransit, paraDestination, paraSource);
}// Of if
}// Of hanoi
/**
* Test the hanoi function.
*/
void hanoiTest() {
printf("---- addToTest begins. ----\r\n");
printf(" \r\n 3 plates\r\n");
hanoi(3, 'A', 'B', 'C');
printf("\r\n 4 plates\r\n");
hanoi(4, 'A', 'B', 'C');
printf("\r\n---- addToTest ends. ----\r\n");
}// Of addToTest
/**
The entrance.
*/
int _tmain(int argc, _TCHAR* argv[])
{
hanoiTest();
return 0;
}// of tmain
输出:
3层塔:
4层塔:
1 自顶向下,逐步求精
目前软件开发方法使用最广泛的,当属结构化的方法和面向对象的方法。其中,结构化程序设计支持“自顶向下,逐步求精”的程序设计方法。
一个非常简洁而有力的例子,把大象装进冰箱,不管多么离谱,终归是将原问题分解为:开冰箱,装大象,关冰箱。其中开关冰箱是两个小问题,和原问题相比,装大象是一个中问题。
2 分治与递归
把hanoi塔问题视为一个函数、操作,n个盘子的出发柱A转移到目标柱B,记作A -n-> B,该操作需要借助的过渡柱C,并满足相应规则。
那么必然有:
该过程就实现了分治:把一个大问题分解为完全相同的小问题。用递归可以很好的实现,参看代码。
3 一些细节
- 不要跨层分析,在设计时也不需要太关注细节;
- 函数定义时的形参命名一定要规范,并注意与实际调用函数时的实参进行对比;
- 汉诺塔问题本身是非常简单的,只要明白n层塔的转移可分解为两次n-1层塔的转移和一次中间转移,那么逻辑上,乃至代码上都是足够清晰和简洁的;
- 但通过打印地址和辅助输出,来仔细理解整个过程——尤其是在计算机内的运转过程,这是非常重要的。
4 时间复杂度
O
(
2
n
)
O(2^n)
O(2n)
说明:由
T
(
n
)
=
T
(
n
−
1
)
+
1
+
T
(
n
−
1
)
=
2
T
(
n
−
1
)
+
1
→
T
n
+
1
=
2
(
T
n
−
1
+
1
)
T(n)=T(n-1)+1+T(n-1)=2T(n-1)+1\rightarrow T_n+1=2(T_{n-1}+1)
T(n)=T(n−1)+1+T(n−1)=2T(n−1)+1→Tn+1=2(Tn−1+1)
→
T
n
+
1
=
(
T
1
+
1
)
n
−
1
=
2
n
→
T
n
=
2
n
−
1
\rightarrow T_n+1=(T_1+1)^{n-1}=2^n \rightarrow T_n=2^n-1
→Tn+1=(T1+1)n−1=2n→Tn=2n−1
5 空间复杂度
O
(
n
)
O(n)
O(n)
说明:红框里就是栈,n个盘子时一直没超过n,代码详细地展示了整个运行过程,不再详述。