漢諾塔:漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。
基本介紹
- 中文名稱:漢諾塔
- 外文名稱:Tower of Hanoi
- 又稱:河內塔
由來及傳說
由來
印度傳說
相關預言
其他相關
宇宙壽命
經典題目
算法介紹
程式實現
Python
def hanoi(n, a, b, c): if n == 1: print(a, '-->', c) else: hanoi(n - 1, a, c, b) print(a, '-->', c) hanoi(n - 1, b, a, c)# 調用hanoi(5, 'A', 'B', 'C')
C語言
#include <stdio.h>#include <windows.h>void Hanoi(int n, char a,char b,char c);void Move(int n, char a, char b);int count;int main(){ int n=8; printf("漢諾塔的層數:\n"); scanf(" %d",&n); Hanoi(n, 'A', 'B', 'C'); Sleep(20000); return 0;}void Hanoi(int n, char a, char b, char c){ if (n == 1) { Move(n, a, c); } else { Hanoi(n - 1, a, c, b); Move(n, a, c); Hanoi(n - 1, b, a, c); }}void Move(int n, char a, char b){ count++; printf("第%d次移動 Move %d: Move from %c to %c !\n",count,n,a,b);}
C HANOI LIST PROGRAM MAIN INTEGER N PRINT *, "ENTER THE AMOUNT OF STEP:" READ *, N CALL HANOI(N,'A','B','C') END RECURSIVE SUBROUTINE HANOI(N,START,STATION,AIM) INTEGER N CHARACTER :: START, STATION, AIM IF (N.EQ.1) THEN CALL MOVE(START,AIM) ELSE CALL HANOI(N-1,START,AIM,STATION) CALL MOVE(START,AIM) CALL HANOI(N-1,STATION,START,AIM) END IF END SUBROUTINE SUBROUTINE MOVE(START, AIM) CHARACTER :: START, AIM PRINT *, START, " -> ", AIM END SUBROUTINE
#include<stdio.h>#include<math.h>#include<stdlib.h>//第0位置是柱子上的塔盤數目intzhua[100]= {0},zhub[100]= {0},zhuc[100]= {0};charcharis(charx,intn)//左右字元出現順序固定,且根據n值奇偶爾不同{ switch(x) { case'A': return(n%2==0)?'C':'B'; case'B': return(n%2==0)?'A':'C'; case'C': return(n%2==0)?'B':'A'; default: return'0'; }}voidprint(charlch,charrch)//列印字元{ if(lch=='A') { switch(rch) { case'B': zhub[0]++; zhub[zhub[0]]=zhua[zhua[0]]; zhua[zhua[0]]=0; zhua[0]--; break; case'C': zhuc[0]++; zhuc[zhuc[0]]=zhua[zhua[0]]; zhua[zhua[0]]=0; zhua[0]--; break; default: break; } } if(lch=='B') { switch(rch) { case'A': zhua[0]++; zhua[zhua[0]]=zhub[zhub[0]]; zhub[zhub[0]]=0; zhub[0]--; break; case'C': zhuc[0]++; zhuc[zhuc[0]]=zhub[zhub[0]]; zhub[zhub[0]]=0; zhub[0]--; break; default: break; } } if(lch=='C') { switch(rch) { case'A': zhua[0]++; zhua[zhua[0]]=zhuc[zhuc[0]]; zhuc[zhuc[0]]=0; zhuc[0]--; break; case'B': zhub[0]++; zhub[zhub[0]]=zhuc[zhuc[0]]; zhuc[zhuc[0]]=0; zhuc[0]--; break; default: break; } } printf("\t"); inti; printf("("); for(i=1; i<=zhua[0]; i++) printf("%d",zhua[i]); printf(")"); printf("("); for(i=1; i<=zhub[0]; i++) printf("%d",zhub[i]); printf(")"); printf("("); for(i=1; i<=zhuc[0]; i++) printf("%d",zhuc[i]); printf(")"); printf("\n");}voidHannuo(intn){//分配2^n個空間 bool*isrev; isrev=(bool*)malloc(sizeof(bool)*(int)pow(2,n)); for(inti=1; i<pow(2,n);i++)isrev[i]=false;//循環計算是否逆序for(intci=2; ci<=n; ci++){ for(intzixh=(int)pow(2,ci-1);zixh<pow(2,ci); zixh+=4)//初始值重複一次,自增值可加4,減少循環次數。 isrev[zixh]=isrev[(int)pow(2,ci)-zixh];//該位置為中間位置,且奇次冪逆序,偶數冪不逆序 isrev[(int)pow(2,ci)]=((ci-1)%2==0)?false:true; } charlch='A',rch; rch=(n%2==0?'B':'C'); printf("%d\t",1); printf("%c->%c",lch,rch); print(lch,rch); for(intk=2; k<pow(2,n); k++){ if(k%2==0) rch=charis(lch,n); else lch=charis(rch,n); printf("%d\t",k); if(isrev[k]) { printf("%c->%c",rch,lch); print(rch,lch); } else { printf("%c->%c",lch,rch); print(lch,rch); } }}intmain(){ intn; printf("Inputthenum:"); scanf("%d",&n); zhua[0]=n; for(inti=1; i<=n; i++) zhua[i]=n-i+1; Hannuo(n); return0;}
遞歸
#include <iostream>using namespace std; template<int n> void hanoi(char a, char b, char c){ hanoi<n - 1>(a, c, b); printf("%c -> %c\n", a, c); hanoi<n - 1>(b, a, c);}template<>void hanoi<1>(char a, char b, char c){ printf("%c -> %c\n", a, c);}////////////////////////////////////////////////template<int n, char a, char b, char c> class hanoi1{public: static int hanoi(){ hanoi1<n-1, a, c, b>::hanoi(); printf("%c -> %c\n", a, c); hanoi1<n-1, b, a, c>::hanoi(); }};template<char a, char b, char c>class hanoi1<1, a, b ,c>{public: static int hanoi(){ printf("%c -> %c\n", a, c); }};int main(){ #define N 4 cout<<"類模板偏特化:"; hanoi1<N,'A','B','C'>::hanoi(); cout<<endl; cout<<"函式模板全特化:"; hanoi<3>('A','B','C'); exit(0);}
C#
using System;class HANOI{ private static int time = 0; static void Main(string[] args) { Hanoi(3, "x", "y", "z"); Console.WriteLine(time + " Times"); Console.ReadKey(); } public static void Hanoi(int n, string x, string y, string z) { if (n == 1) { Console.WriteLine(x + "--->" + z); time++; } else { Hanoi(n - 1, x, z, y); Hanoi(1, x, y, z); Hanoi(n - 1, y, x, z); } }}
Java
public class Hanoi { /** * * @param n 盤子的數目 * @param origin 源座 * @param assist 輔助座 * @param destination 目的座 */ public void hanoi(int n, char origin, char assist, char destination) { if (n == 1) { move(origin, destination); } else { hanoi(n - 1, origin, destination, assist); move(origin, destination); hanoi(n - 1, assist, origin, destination); } } // Print the route of the movement private void move(char origin, char destination) { System.out.println("Direction:" + origin + "--->" + destination); } public static void main(String[] args) { Hanoi hanoi = new Hanoi(); hanoi.hanoi(3, 'A', 'B', 'C'); }}
php
漢諾塔主要是有三個塔座X,Y,Z,要求將三個大小不同,依小到大編號為1,2.....n的圓盤從A移動到塔座Z上,要求
(1):每次只能移動一個圓盤
(2):圓盤可以插到X,Y,Z中任一塔座上
(3):任何時候不能將一個較大的圓盤壓在較小的圓盤之上
主要是運用了遞歸的思想,這裡使用php做個簡單的實現......
<?php function hanoi($n,$x,$y,$z){ if($n==1){ move($x,1,$z); }else{ hanoi($n-1,$x,$z,$y); move($x,$n,$z); hanoi($n-1,$y,$x,$z); } } function move($x,$n,$z){ echo'movedisk'.$n.'from'.$x.'to'.$z.'<br>'; } hanoi(10,'x','y','z'); ?>
pascal
var m:integer;procedure move(getone,putone:char);begin writeln(getone,'->',putone) end;procedure hanoi(n:integer;one,two,three:char);beginif n=1 then move(one,three) elsebeginhanoi(n-1,one,three,two);move(one,three);hanoi(n-1,two,one,three)endend;beginreadln(m);write('the step to moving disks:');writeln;hanoi(m,'A','B','C')end.
Lua
function hanoi(num, a,b,c) if (num == 1) then print(a .."-->"..c) else hanoi(num-1, a,c,b) print(a .."-->"..c) hanoi(num-1, b,a,c) endendhanoi(3,'A','B','C')
易語言
JavaScript
var hanoi=function(n,from,ass,to){ if(n>0){ hanoi(n-1,from,to,ass); move(n,from,to); hanoi(n-1,ass,from,to); }}var move=function(n,from,to){ console.log("移動第"+n+"個從"+from+"到"+to);}hanoi(3,"A","B","C");