从递归算法思想解析汉诺塔问题

汉诺塔 – 问题起源

法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。

汉诺塔游戏

后来,这个传说就演变为汉诺塔游戏:

1.有三根杆子A,B,C。A杆上有若干碟子  

2.每次移动一块碟子,小的只能叠在大的上面  

3.把所有碟子从A杆全部移到C杆上

解决思路

A柱子有7块盘子时,可借助B将A柱子的盘子全部移至C柱子,由小到大从上往下摆放

游戏的起始状态,A柱子7块盘子,移至C柱子:

 

 《从递归算法思想解析汉诺塔问题》

 

要实现游戏,需将A柱子红色盘子上面的6块借助C移至B柱子,盘子由小到大从上往下摆放,在将最大的红色盘子由A柱子移至C柱子,此时A柱子没有盘子,这个时候是游戏的一个临界状态,最大的红色盘子有序的摆放在C柱子(现在可以不管红色盘子了,因为最大的如果你把它放那不动,则可以无视它的,其他盘子可以在三个柱子上移来移去.它是最大嘛),接着需要将B柱子的6块盘子借助A移动到C柱子,即可完成汉诺塔游戏了。这个过程中,7块盘子的汉诺塔游戏可演变为2个6块盘子的汉诺塔游戏了,2个6块盘子的汉诺塔游戏了演变成4个5块盘子的汉诺塔游戏了……,递归的出口就是只有一块盘子的时候了,直接移动盘子,这就是经典递归思想了

游戏的临界状态,B柱子6块盘子,移动至C柱子

 
 

《从递归算法思想解析汉诺塔问题》

时间复杂度计算

汉诺塔问题是一个经典的“重复问题“(recurrent problem),解法也从中所知,最少移动步骤是2^n – 1。

n个盘子,ABC三个地点,将A上的n个盘子移动到C上。最少的步骤是多少?

AC[n] = AB[n-1] + AC[1] + BC[n-1]

因为AC[n] = BC[n] = AB[n] = T(n)

所以以上等式可以写成

T(n) = T(n-1) + 1 + T(n-1)=2^1*T(n-1)+1=2^2*T(n-2)+1=……=2^n-1*T(n-(n-1))+1=2^n-1*T(1))+1,从而得到T(n) = 2^n – 1

php代码

    private function hanoi_r($n,$a,$b,$c){
        if($n==1){
            $this->move($a,1,$c);
        }else{
            $this->hanoi_r($n-1,$a,$c,$b);
            $this->move($a,$n,$c);
            $this->hanoi_r($n-1,$b,$a,$c);
        }
    }
    private function move($a,$n,$c){
        echo 'move disk '.$n.' from '.$a.' to '.$c.'<br/>';
    }

    public function hanoi($n){
        $this->hanoi_r($n,'a','b','c');
    }

    原文作者:递归算法
    原文地址: https://blog.csdn.net/jespere_ling/article/details/48657161
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞