汉诺塔问题:
有三根竖着的木棍,其中一根木棍上串着N个自下而上逐渐变小的圆盘,现在要求将N个盘子从A木棍移动到C木棍上,且满足以下两个条件:
1.无论何时,任何圆盘上方不能有比他更大的圆盘
2.一次只能移动一个圆盘
问:如何移动才能达到要求?
解题步骤:
假设要移动n个单位, 起始点是A, 目标地点是C, 中间点是B
那么问题可以分为以下步骤:
step 1:n-1个单位由 A 移动到 B
step 2:1个单位由 A 移动到 C
step 3:n-1个单位由 B 移动到 C
其中step 1 和 step 2 又可以拆分为这三个步骤,直到只有一个单位
那么问题的算法就出来了:
循环体:step1 step2 step3
终止条件:直到只有一个单位
//递归 void move(char A, char B, char C, int Ahigh) { if(Ahigh == 1)//结束条件 step(A,C); else//循环体 { move(A,C,B,Ahigh-1); step(A,C); move(B,A,C,Ahigh-1); } }
*step函数的功能是将 A->C 打印在控制台上
解题思考:
很能体现递归思想的汉诺塔问题,当一个复杂的问题,可以拆分为有一定规律的步骤时,便可以使用递归的方法来解决。
实际上递归也是一种循环,笔者认为,凡是可以使用递归解决的问题,循环都可以做到,递归的优缺点也比较明显:
递归:
优点:可以更加清晰的表达自己的思路,让自己的程序变得更加美观;
缺点:我们知道,递归是在不断的调用自身,也就是不断地在调用一个函数,而当一段程序在进入某一个函数时,都要做一件事:保存返回地址和现场,通常是以压栈的形式进行,而这样做就会增加程序运行时额外的开销,对于一些深层的递归,还可能导致栈溢出。
综上所述:
通过权衡时间效益和代码可读性,选择合适的算法作为最终的目标;
浙公网安备 33010602011771号