日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

汉诺塔非递归算法

發布時間:2025/5/22 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 汉诺塔非递归算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這兩天講《Web程序設計》,用JavaScript寫了個漢諾塔的非遞歸算法,覺得有點意思,放在這里吧!

傳統的遞歸算法:?

  • <html?xmlns="http://www.w3.org/1999/xhtml">?
  • <head>?
  • <meta?http-equiv="Content-Type"?content="text/html;?charset=utf-8"?/>?
  • <title>Hanoi?Tower?(Recursive?algorithm)?-?漢諾塔(遞歸算法)</title>?
  • <style?type="text/css">?
  • i?{ ?
  • ????color:?#0000ff; ?
  • } ?
  • P?{ ?
  • ????text-align:?center; ?
  • } ?
  • </style>?
  • <script?type="text/javascript">?
  • var?step=0; ?
  • function?MoveOnePlate(n,?loca1,?loca2) ?
  • { ?
  • ????document.write("第"?+?++step?+?"步:移動第<i>"?+?n?+?"</i>個盤子,從"?+?loca1?+?"到"?+?loca2?+?"<br?/>"); ?
  • } ?
  • ?
  • function?MovePlates(n,?s,?m,?d) ?
  • { ?
  • ????if(n==1) ?
  • ??????MoveOnePlate(n,?s,?d); ?
  • ????else ?
  • ????{ ?
  • ????????MovePlates(n-1,?s,?d,?m); ?
  • ????????MoveOnePlate(n,?s,?d); ?
  • ????????MovePlates(n-1,?m,?s,?d); ?
  • ????} ?
  • } ?
  • </script>?
  • </head>?
  • ?
  • <body>?
  • <p>Hanoi?Tower?(Recursive?algorithm)?-?漢諾塔(遞歸算法)<br?/>Mengliao?Software?Studio(Baiyu)?-?夢遼軟件工作室(白宇)<br?/>?
  • Copyright?2011,?All?right?reserved.?-?版權所有(C)?2011<br?/>2011.03.31</p>?
  • <script?type="text/javascript">?
  • ????n=parseInt(prompt("請輸入盤子的數量:",?3),?10); ?
  • ????if?(isNaN(n)?||?n<1?||?n>16) ?
  • ????{ ?
  • ????????alert("請輸入介于1到16的自然數!"); ?
  • ????????location.reload(); ?
  • ????} ?
  • ????else ?
  • ????{ ?
  • ????????document.write("共"?+?n?+?"個盤子,需移動"?+?(Math.pow(2,?n)-1)?+?"步:<br?/><br?/>"); ?
  • ????????MovePlates(n,?"<i>源點</i>",?"<i>臨時</i>",?"<i>目標</i>"); ?
  • ????} ?
  • </script>?
  • </body>?
  • </html>?
  • 這個遞歸算法就不詳細說了,核心代碼只有5、6行。
    下面是非遞歸算法:?

  • <html?xmlns="http://www.w3.org/1999/xhtml">?
  • <head>?
  • <meta?http-equiv="Content-Type"?content="text/html;?charset=utf-8"?/>?
  • <title>Hanoi?Tower?(Non-recursive?algorithm)?-?漢諾塔(非遞歸算法)</title>?
  • <style?type="text/css">?
  • i?{ ?
  • ????color:?#ff0000; ?
  • } ?
  • p?{ ?
  • ????text-align:?center; ?
  • } ?
  • </style>?
  • <!-- ?
  • 漢諾塔非遞歸算法: ?
  • (1)、若問題規模n為偶數,按順時針方向依次擺放s,?m,?d為環,若n為奇數,則為s,?d,?m; ?
  • (2)、將盤子由小到大逐個編號并放置在s上,即最小的盤子編號為1,放在最上面; ?
  • (3)、按順時針方向把編號為1的盤子從當前的位置移動到下一位置; ?
  • (4)、把另外兩個位置(即除去1號盤子所在的位置)中非空的那個上的一個圓盤移到空的位置上,如果另外兩個位置都非空,則移動編號較小的那一個; ?
  • (5)、重復進行(3)和(4),直到移動的次數等于2^n-1。 ?
  • -->?
  • <script?type="text/javascript">?
  • var?step=0; ?
  • function?MoveOnePlate(n,?loca1,?loca2) ?
  • { ?
  • ????document.write("第"?+?++step?+?"步:移動第<i>"?+?n?+?"</i>個盤子,從"?+?loca1?+?"到"?+?loca2?+?"<br?/>"); ?
  • } ?
  • ?
  • function?MovePlates(n,?s,?m,?d) ?
  • { ?
  • ????//定義位置 ?
  • ????var?loop=new?Array(3); ?
  • ????loop[0]=new?Array(n); ?
  • ????loop[1]=new?Array(n); ?
  • ????loop[2]=new?Array(n); ?
  • ????//定義位置描述字符串數組(n為偶數的情況) ?
  • ????var?loca=new?Array(s,?m,?d); ?
  • ????if?(n%2!=0)?//n為奇數的情況 ?
  • ????{ ?
  • ????????loca[1]=d; ?
  • ????????loca[2]=m; ?
  • ????} ?
  • ????//初始化源位置上的盤子 ?
  • ????for(var?i=0;?i<n;?i++) ?
  • ????????loop[0][i]=n-i; ?
  • ????//記錄各個位置上盤子的數量 ?
  • ????var?loopLen=new?Array(n,?0,?0); ?
  • ????var?count=Math.pow(2,?n)-1;?//移動次數,即循環退出條件 ?
  • ????var?firstPlate=0;?//1號盤子的位置 ?
  • ????do ?
  • ????{ ?
  • ????????//將1號盤子順時針移動到后1個位置 ?
  • ????????MoveOnePlate(1,?loca[firstPlate],?loca[(firstPlate+1)%3]);?//顯示移動過程 ?
  • ????????loop[(firstPlate+1)%3][loopLen[(firstPlate+1)%3]]=1;?//移動 ?
  • ????????loopLen[firstPlate]--;?//修改1號盤子舊位置上盤子的數量 ?
  • ????????firstPlate=(firstPlate+1)%3;?//修改1號盤子的位置 ?
  • ????????loopLen[firstPlate]++;?//修改1號盤子新位置上盤子的數量 ?
  • ????????count--;?//記錄移動次數 ?
  • ????????//移動另外的兩個位置上的盤子 ?
  • ????????if(count!=0)?//避免最后一次移動后仍然移動而導致錯誤 ?
  • ????????{ ?
  • ????????????//確定另外兩個位置如何移動 ?
  • ????????????if?(loopLen[(firstPlate+1)%3]==0?||?loopLen[(firstPlate+2)%3]!=0?&& ?
  • ????????????????loop[(firstPlate+2)%3][loopLen[(firstPlate+2)%3]-1]?<?loop[(firstPlate+1)%3][loopLen[(firstPlate+1)%3]-1]?) ?
  • ????????????{?//1號盤子的后第1個位置為空,或者無空位置且1號盤子后第2個位置編號較小,此時將1號盤子后第2個位置的盤子移動到1號盤子后第1個位置上 ?
  • ????????????????MoveOnePlate(loop[(firstPlate+2)%3][loopLen[(firstPlate+2)%3]-1],?loca[(firstPlate+2)%3],?loca[(firstPlate+1)%3]);?//顯示移動過程 ?
  • ????????????????loop[(firstPlate+1)%3][loopLen[(firstPlate+1)%3]]=loop[(firstPlate+2)%3][loopLen[(firstPlate+2)%3]-1];?//移動 ?
  • ????????????????loopLen[(firstPlate+2)%3]--;?//修改該盤子舊位置上盤子的數量 ?
  • ????????????????loopLen[(firstPlate+1)%3]++;?//修改該盤子新位置上盤子的數量 ?
  • ????????????} ?
  • ????????????else ?
  • ????????????{?//1號盤子的后第2個位置為空,或者無空位置且1號盤子后第1個位置編號較小,此時將1號盤子后第1個位置的盤子移動到1號盤子后第2個位置上 ?
  • ????????????????MoveOnePlate(loop[(firstPlate+1)%3][loopLen[(firstPlate+1)%3]-1],?loca[(firstPlate+1)%3],?loca[(firstPlate+2)%3]);?//顯示移動過程 ?
  • ????????????????loop[(firstPlate+2)%3][loopLen[(firstPlate+2)%3]]=loop[(firstPlate+1)%3][loopLen[(firstPlate+1)%3]-1];?//移動 ?
  • ????????????????loopLen[(firstPlate+1)%3]--;?//修改該盤子舊位置上盤子的數量 ?
  • ????????????????loopLen[(firstPlate+2)%3]++;?//修改該盤子新位置上盤子的數量 ?
  • ????????????} ?
  • ????????????count--;?//記錄移動次數 ?
  • ????????} ?
  • ????}?while(count!=0) ?
  • } ?
  • </script>?
  • </head>?
  • ?
  • <body>?
  • <p>Hanoi?Tower?(Non-recursive?algorithm)?-?漢諾塔(非遞歸算法)<br?/>Mengliao?Software?Studio(Baiyu)?-?夢遼軟件工作室(白宇)<br?/>?
  • Copyright?2011,?All?right?reserved.?-?版權所有(C)?2011<br?/>2011.03.31</p>?
  • <script?type="text/javascript">?
  • ????n=parseInt(prompt("請輸入盤子的數量:",?3),?10); ?
  • ????if?(isNaN(n)?||?n<1?||?n>16) ?
  • ????{ ?
  • ????????alert("請輸入介于1到16的自然數!"); ?
  • ????????location.reload(); ?
  • ????} ?
  • ????else ?
  • ????{ ?
  • ????????document.write("共"?+?n?+?"個盤子,需移動"?+?(Math.pow(2,?n)-1)?+?"步:<br?/><br?/>"); ?
  • ????????MovePlates(n,?"<i>源點</i>",?"<i>臨時</i>",?"<i>目標</i>"); ?
  • ????} ?
  • </script>?
  • </body>?
  • </html>?
  • 非遞歸算法略微復雜些,代碼里面有詳細的注釋和說明。

    這里還有一個使用JavaScript數組對象的push()和pop()方法的非遞歸版本,可以簡化程序,道理是一樣的。
    非遞歸算法版本2:?

  • <html?xmlns="http://www.w3.org/1999/xhtml">?
  • <head>?
  • ????<meta?http-equiv="Content-Type"?content="text/html;?charset=utf-8"?/>?
  • ????<title>Hanoi?Tower?(Non-recursive?algorithm,?Version?2)?-?漢諾塔(非遞歸算法,版本2)</title>?
  • ????<style?type="text/css">?
  • ????????i ?
  • ????????{ ?
  • ????????????color:?#ff0080; ?
  • ????????} ?
  • ????????p ?
  • ????????{ ?
  • ????????????text-align:?center; ?
  • ????????} ?
  • ????</style>?
  • ????<!-- ?
  • 漢諾塔非遞歸算法: ?
  • (1)、若問題規模n為偶數,按順時針方向依次擺放s,?m,?d為環,若n為奇數,則為s,?d,?m; ?
  • (2)、將盤子由小到大逐個編號并放置在s上,即最小的盤子編號為1,放在最上面; ?
  • (3)、按順時針方向把編號為1的盤子從當前的位置移動到下一位置; ?
  • (4)、把另外兩個位置(即除去1號盤子所在的位置)中非空的那個上的一個圓盤移到空的位置上,如果另外兩個位置都非空,則移動編號較小的那一個; ?
  • (5)、重復進行(3)和(4),直到移動的次數等于2^n-1。 ?
  • -->?
  • ????<script?type="text/javascript">?
  • ????????var?step?=?0; ?
  • ????????function?MoveOnePlate(n,?loca1,?loca2)?{ ?
  • ????????????document.write("第"?+?++step?+?"步:移動第<i>"?+?n?+?"</i>個盤子,從"?+?loca1?+?"到"?+?loca2?+?"<br?/>"); ?
  • ????????} ?
  • ?
  • ????????function?MovePlates(n,?s,?m,?d)?{ ?
  • ????????????//定義位置 ?
  • ????????????var?loop?=?new?Array([],?[],?[]); ?
  • ????????????//定義位置描述字符串數組(n為偶數的情況) ?
  • ????????????var?loca?=?new?Array(s,?m,?d); ?
  • ????????????if?(n?%?2?!=?0)?//n為奇數的情況 ?
  • ????????????{ ?
  • ????????????????loca[1]?=?d; ?
  • ????????????????loca[2]?=?m; ?
  • ????????????} ?
  • ????????????//初始化源位置上的盤子 ?
  • ????????????for?(var?i?=?0;?i?<?n;?i++) ?
  • ????????????????loop[0].push(n?-?i); ?
  • ????????????var?count?=?Math.pow(2,?n)?-?1;?//移動次數,即循環退出條件 ?
  • ????????????var?firstPlate?=?0;?//1號盤子的位置 ?
  • ????????????do?{ ?
  • ????????????????//將1號盤子順時針移動到后1個位置 ?
  • ????????????????MoveOnePlate(1,?loca[firstPlate],?loca[(firstPlate?+?1)?%?3]);?//顯示移動過程 ?
  • ????????????????loop[(firstPlate?+?1)?%?3].push(loop[firstPlate].pop());?//從舊位置移動到新位置 ?
  • ????????????????firstPlate?=?(firstPlate?+?1)?%?3;?//修改1號盤子的位置 ?
  • ????????????????count--;?//記錄移動次數 ?
  • ????????????????//移動另外的兩個位置上的盤子 ?
  • ????????????????if?(count?!=?0)?//避免最后一次移動后仍然移動而導致錯誤 ?
  • ????????????????{ ?
  • ????????????????????//確定另外兩個位置如何移動 ?
  • ????????????????????if?(loop[(firstPlate?+?1)?%?3].length?==?0?||?loop[(firstPlate?+?2)?%?3].length?!=?0?&&?loop[(firstPlate?+?2)?%?3][loop[(firstPlate?+?2)?%?3].length?-?1]?<?loop[(firstPlate?+?1)?%?3][loop[(firstPlate?+?1)?%?3].length?-?1])?{ ?
  • ????????????????????????//1號盤子的后第1個位置為空,或者無空位置且1號盤子后第2個位置編號較小,此時將1號盤子后第2個位置的盤子移動到1號盤子后第1個位置上 ?
  • ????????????????????????MoveOnePlate(loop[(firstPlate?+?2)?%?3][loop[(firstPlate?+?2)?%?3].length?-?1],?loca[(firstPlate?+?2)?%?3],?loca[(firstPlate?+?1)?%?3]);?//顯示移動過程 ?
  • ????????????????????????loop[(firstPlate?+?1)?%?3].push(loop[(firstPlate?+?2)?%?3].pop());?//從舊位置移動到新位置 ?
  • ????????????????????} ?
  • ????????????????????else?{ ?
  • ????????????????????????//1號盤子的后第2個位置為空,或者無空位置且1號盤子后第1個位置編號較小,此時將1號盤子后第1個位置的盤子移動到1號盤子后第2個位置上 ?
  • ????????????????????????MoveOnePlate(loop[(firstPlate?+?1)?%?3][loop[(firstPlate?+?1)?%?3].length?-?1],?loca[(firstPlate?+?1)?%?3],?loca[(firstPlate?+?2)?%?3]);?//顯示移動過程 ?
  • ????????????????????????loop[(firstPlate?+?2)?%?3].push(loop[(firstPlate?+?1)?%?3].pop());?//從舊位置移動到新位置 ?
  • ????????????????????} ?
  • ????????????????????count--;?//記錄移動次數 ?
  • ????????????????} ?
  • ????????????}?while?(count?!=?0) ?
  • ????????} ?
  • ????</script>?
  • </head>?
  • <body>?
  • ????<p>?
  • ????????Hanoi?Tower?(Non-recursive?algorithm,?Version?2)?-?漢諾塔(非遞歸算法,版本2)<br?/>?
  • ????????Mengliao?Software?Studio(Baiyu)?-?夢遼軟件工作室(白宇)<br?/>?
  • ????????Copyright?2011,?All?right?reserved.?-?版權所有(C)?2011<br?/>?
  • ????????2011.04.04</p>?
  • ????<script?type="text/javascript">?
  • ????????n?=?parseInt(prompt("請輸入盤子的數量:",?3),?10); ?
  • ????????if?(isNaN(n)?||?n?<?1?||?n?>?16)?{ ?
  • ????????????alert("請輸入介于1到16的自然數!"); ?
  • ????????????location.reload(); ?
  • ????????} ?
  • ????????else?{ ?
  • ????????????document.write("共"?+?n?+?"個盤子,需移動"?+?(Math.pow(2,?n)?-?1)?+?"步:<br?/><br?/>"); ?
  • ????????????MovePlates(n,?"<i>源點</i>",?"<i>臨時</i>",?"<i>目標</i>"); ?
  • ????????} ?
  • ????</script>?
  • </body>?
  • </html>?
  • 這里是三個算法網頁源文件的連接:
    http://mengliao.blog.51cto.com/attachment/201104/876134_1301907387.rar










    本文轉自 BlackAlpha 51CTO博客,原文鏈接:http://blog.51cto.com/mengliao/534053,如需轉載請自行聯系原作者

    總結

    以上是生活随笔為你收集整理的汉诺塔非递归算法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。