汉诺塔问题的思考

#include <stdio.h>
 
/**
*递归处理汉诺塔
*/
void hanoi(int paraN, char paraSource, char paraDestination, char paraTransit)
{
	if (paraN == 0) return;
	else
	{
		hanoi(paraN - 1, paraSource, paraTransit, paraDestination);
		printf("%c -> %c\n", paraSource, paraDestination);
		printf("%p -> %p\n", &paraSource, &paraDestination);
		hanoi(paraN - 1, paraTransit, paraDestination, paraSource);
	}
}
 
/**
*测试函数,使用两个例子进行测试。将三根柱子设为a,b,c。
*/
void hanoiTest()
{
	printf("--- addToTest begins. ---\n");
 
	printf("2 plates\n");
	hanoi(2, 'A', 'B', 'C');
 
	printf("3 plates\n");
	hanoi(3, 'A', 'B', 'C');
 
	printf("---- addToTest ends. ---\n");
}
 
void main()
{
	hanoiTest();
}

 计算机执行指令只能一条一条依次执行,因此运用栈结构,先进栈的指令被压在底层,后进栈的指令放在上层,指令遵循先进后出,后进先出的原则进行运行。当调运递归函数hanoi时,将前面的函数又一次压栈,底层栈的调用结束后,开始执行读取指令,从栈顶指令开始执行,将结果返回下一层函数。

 

1.自顶向下,逐渐求精,函数调用:汉诺塔问题的实现是运用了栈的原理,将函数指令依次压栈,自顶向下依次弹栈,依靠后进先出,先进后出的原则,逐步解决,运用了递归函数的思想进行函数调用,解决了这一问题。

2.递归与分治:递归只能以递归的思想来理解,通俗一点就是外包,假设有N个人,第N个人只需要做第N件事情,剩下的N-1件事情外包给第N-1个人来做,以此类推,每个人都只需要做自己当前所做的事,其他的事情外包给剩下的人做,至于他们怎么做,不关我的事,这就是分治。

3.不要跨层分析:在2.中已经大概分析过,递归分治的基本就是不要跨层分析,这一层的函数我们只需要考虑本层函数该执行的指令,至于剩下的函数,不关本层函数的事。

4.形参与实参:形参是在函数内部命名的参数,在函数内部发挥作用,可以作为实参的载体,在函数结束时回收。而实参是在函数头命名的参数,可以将值传给形参,不会在函数结束时回收。

5.有意义、规范的标识符:在编写代码时我们的格式一定要规范清晰,不仅仅是让我们自己能读懂更重要的是让别人也读懂,例如在hanoi问题中,三个柱子的命名为Source,transit,destination,而不是简单的ABC,这让别人一眼能够快速进入代码并理解代码。

6.时间复杂度: 我们假设Hanoi的执行时间是T(n),此递归函数中语句if(n==1)move(A, 1, C);的执行时间是O(1);else中递归调用的执行时间是T(n-1),赋值执行时间为O(1),所以执行时间是O(1) + T(n-1)。那么可以得到如下递归方程:

 T(n) = \begin{cases} & O(1), \text{ } n=1 \\ & 2*T(n-1) + O(1), \text{ } n>1 \end{cases}

具体运算过程:

T(n) = 2T(n-1) + O(1);

T(n-1) = 2T(n-2) + O(1);

...

T(2) = 2T(1) + O(1).

除第一个式子之外全部*2,并加到上一个式子中,得到:

  所以汉诺塔递归解法程序的时间复杂度是2^nO(1)。结果时间复杂度为O(2^n)【摘自博主:Kashine】

7.递归栈:建立在栈的基础之上,在第一个函数完成指令后弹栈,递归函数调用又将函数压栈,依次反复进行,直到该递归栈完成指令,这就是递归栈,本质是递归函数的调用和栈原理的结合。

8.空间复杂度:简单来说就是所占用的空间,在递归栈中,若有三个函数占用了3片空间,不论压栈弹栈,始终只有这三个函数,那么他的空间复杂度就可以看作3。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值