分治算法递归——汉诺塔问题

分治算法的精髓即为分治即分而治之,一个问题规模过大不容易直接解决,就可以划分成许多小问题,解决这些小问题,再将小问题的解合并成大问题的解。

递归的精髓就是要找到问题中的重复部分,然后解决该重复部分,把问题的规模减小但是解决的方法不变,在函数里调用自身。大而化小,小而化了。假如一个问题能表示成  类似于“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
    }
}

猜你喜欢

转载自blog.csdn.net/LOG_IN_ME/article/details/82556044