分治算法的精髓即为分治即分而治之,一个问题规模过大不容易直接解决,就可以划分成许多小问题,解决这些小问题,再将小问题的解合并成大问题的解。
递归的精髓就是要找到问题中的重复部分,然后解决该重复部分,把问题的规模减小但是解决的方法不变,在函数里调用自身。大而化小,小而化了。假如一个问题能表示成 类似于“F(n) = F(n-1)的函数 ”,就可以用递归。
汉诺塔问题描述:
有A,B,C三根柱子,A柱上有n个圆盘从上往下圆盘依次增大排列,现想把A柱上的圆盘按原顺序移动到C盘上,而且中间任何过程小圆盘都必须在大圆盘之上,每次只能搬一个盘(即每次只能搬最上面的那一个盘)。
汉诺塔问题分析:
要想找到解决该问题重复的部分,我们要先从简单的情况开始分析,慢慢变复杂以找到规律:
1)当n=1时,只需将A盘上的那一个盘子直接移至C盘即可,A > C。
2)当n=2时,需要借助B柱作为“暂存区”暂存一下小盘,等A柱上的大盘移至C柱后再将B柱上的小盘移至C柱,A > B,A > C,B > C。
3)当n=3时,由于不能改变圆盘顺序,所以最先在C柱的一定是最大的盘,那要想搬动A盘的最大的盘,就要先把上面的2个盘先搬走,而且只能搬到B柱,那怎么将该2个圆盘按顺序移至B盘呢?这时候就回到了当n=2时的情况了,这时候将C柱作为“暂存区”即可实现,最后将A柱上的最大盘移至C柱,然后接着利用n=2的情况将A柱作为“暂存区”将B柱上的盘移至C柱即可。
(A > B),A > C,(B > C),()表示一个n=2时的过程,需要3+1+3=7次。
4)当n=4时,我们就慢慢找到规律了,(A > B),A > C,(B > C),()表示一个n=3的过程,需要7+1+7=15次。
5)我们就找到一般规律了:当n>1时,(A > B),A > C,(B > C),()表示一个n=n-1的过程,需要2^n-1次。
汉诺塔算法描述:
void Hanoi(int n,char A,char B,char C)
{
if(n>0)
{
Hanoi(n-1,A,C,B); //将A上n-1个圆盘移至B,借助C
A > C; //将A最大盘直接移至C
Hanoi(n-1,B,A,C); //将B上n-1个圆盘移至C, 借助B
}
}