K:汉诺塔问题
相關介紹:
?漢諾塔問題是一個通過隱式使用遞歸棧來進行實現的一個經典問題,該問題最早的發明人是法國數學家愛德華·盧卡斯。傳說印度某間寺院有三根柱子,上串64個金盤。寺院里的僧侶依照一個古老的預言,以上述規則移動這些盤子;預言說當這些盤子移動完畢,世界就會滅亡。這個傳說叫做梵天寺之塔問題(Tower of Brahma puzzle)。但不知道是盧卡斯自創的這個傳說,還是他受他人啟發。若傳說屬實,僧侶們需要2^64 ? 1步才能完成這個任務;若他們每秒可完成一個盤子的移動,就需要5845億年才能完成。整個宇宙現在也不過137億年。這個傳說有若干變體:寺院換成修道院、僧侶換成修士等等。寺院的地點眾說紛紜,其中一說是位于越南的河內,所以被命名為“河內塔”。另外亦有“金盤是創世時所造”、“僧侶們每天移動一盤”之類的背景設定。佛教中確實有“浮屠”(塔)這種建筑;有些浮屠亦遵守上述規則而建。“漢諾塔”一名可能是由中南半島在殖民時期傳入歐洲的。
?其問題的形式化描述如下:假設有3個分別命名為X,Y,Z的塔座,在塔座X上插有n個直徑大小各不相同,且從小到大編號為1、2、......、n的圓盤。現要求將塔座X上的n個圓盤借助塔座Y移至塔座Z上,并仍按同樣順序疊排。圓盤移動時必須遵守以下的規則:
問題分析:
?當n=1時,問題較為簡單,只要將編號為1的圓盤從塔座X直接移動到塔座Z上即可;當n>1時,需利用塔座Y作輔助塔座,若能先設法將壓在編號為n的圓盤上的n-1個圓盤從塔座X移動到塔座Y上,則可將編號為n的圓盤從塔座X移動至塔座Z上,然后將塔座Y上的n-1個圓盤移至塔座Z上。而如何將n-1個圓盤從一個塔座移動至另一個塔座是一個和原問題具有相同特征屬性的問題,只是問題的規模小于1,因此可以用同樣的辦法進行求解。由此可知,求解n階漢諾塔問題可以用遞歸分解的方法來進行。
示例代碼如下:
package queueandstack; /*** 該類用于解決漢諾塔問題* @author 學徒**/ public class Hanoi {//用于搬動次數的記錄private int c=0;/*** 將塔座x上按照直徑由小到大且自上而下的編號為1至n的n個圓盤按照規則移到塔座z上,y用作輔助塔座* @param n 圓盤的數目* @param x 原塔座* @param y 輔助塔座* @param z 目標塔座*/public void hanoi(int n,char x,char y,char z){if(n==1)move(x,1,z);//將編號為1的圓盤從x移動到zelse{hanoi(n-1,x,z,y);//將x上編號為1到n-1的圓盤移動到y,z做輔助塔座move(x,n,z);//將編號為n的圓盤從x移動到zhanoi(n-1,y,x,z);//將y上編號為1至n-1的圓盤移動到z,x做輔助塔座}}/*** 用于移動操作* @param x 原塔座* @param n 圓盤編號* @param z 目標塔座*/public void move(char x,int n,char z){System.out.println("第"+(++c)+"次移動:"+n+"號圓盤,"+x+"->"+z);}public static void main(String[] args){Hanoi n=new Hanoi();n.hanoi(3, 'x', 'y', 'z');//對圓盤數量為3進行移動} }運行結果: 第1次移動:1號圓盤,x->z 第2次移動:2號圓盤,x->y 第3次移動:1號圓盤,z->y 第4次移動:3號圓盤,x->z 第5次移動:1號圓盤,y->x 第6次移動:2號圓盤,y->z 第7次移動:1號圓盤,x->z-------------->以上內容大部分來自教材《數據結構》,清華大學出版社
其移動情況的示例圖如下:
回到目錄|·(工)·)
轉載于:https://www.cnblogs.com/MyStringIsNotNull/p/8227632.html
總結
- 上一篇: 为什么禁止超过三张表 join,原理是什
- 下一篇: 我教女朋友学编程Html系列(6)—Ht