漢諾塔算法

 

 

有A、B和C 3跟柱子,在A上從下往上按照從小到大的順序放着64個圓盤,以B爲中介,把盤子所有移動到C上。移動過程當中,要求任意盤子的下面要麼沒有盤子,要麼只能有比它大的盤子。java

 

 * 思想:採用遞歸的方法來接app

 *      1. 先將A上面的n-1個盤子,移到B柱上ui

 *      2. 而後把A上最大的一個盤子放到C上去this

 *      3. 而後把B上面的n-1個盤子移到A上去編碼

 * .net

 * 步驟:code

 *      漢若塔用遞歸思考首先考慮一種臨界狀態,把n-1個上面的盤從A—B, 就是把n從A移動到C,最後把n-1個盤從B---C,orm

 *      (注意在考慮把n-1個盤從B---C的時候就出現遞歸調用,若是把A,B盤交換就又重複上面的流程了,最後到n = 1的時候就返回)遞歸

 * ci

 * 僞代碼:

 *  public void run(int n, char a, char b, char c)

    {

        if(n==1)

        {

            move(n,a,c) //等於1的時候把盤從A移動到C

        }else

        {

            run(n-1,a,b,c);//遞歸調用把a上面的n-1個盤移動到B上,怎麼表示移動?把柱子交換不就是移動了。

            move(n,a,c);

            run(n-1,b,a,c);//意圖是把n-1個盤從B移動到A上。

        }

         

    }      

 *

package cglib;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Hashtable;  

 

public class StringNumber {
    public static void main(String args[]) throws Exception {
                int n;
                BufferedReader buf =
                         new BufferedReader(new InputStreamReader(System.in));
                System.out.print("請輸入盤數:");
                n = Integer.parseInt(buf.readLine());
                StringNumber hanoi = new StringNumber();
                hanoi.move(n, 'A', 'B', 'C');
            }
        
            public void move(int n, char a, char b, char c) {
                if (n == 1)
                     System.out.println("盤 " + n + " 由 " + a + " 移至 " + c);
                else {
                    move(n - 1, a, c, b);
                    System.out.println("盤 " + n + " 由 " + a + " 移至 " + c);
                     move(n - 1, b, a, c);
                 }
             }
    
}
      


輸出:

請輸入盤數:5
盤 1 由 A 移至 C
盤 2 由 A 移至 B
盤 1 由 C 移至 B
盤 3 由 A 移至 C
盤 1 由 B 移至 A
盤 2 由 B 移至 C
盤 1 由 A 移至 C
盤 4 由 A 移至 B
盤 1 由 C 移至 B
盤 2 由 C 移至 A
盤 1 由 B 移至 A
盤 3 由 C 移至 B
盤 1 由 A 移至 C
盤 2 由 A 移至 B
盤 1 由 C 移至 B
盤 5 由 A 移至 C
盤 1 由 B 移至 A
盤 2 由 B 移至 C
盤 1 由 A 移至 C
盤 3 由 B 移至 A
盤 1 由 C 移至 B
盤 2 由 C 移至 A
盤 1 由 B 移至 A
盤 4 由 B 移至 C
盤 1 由 A 移至 C
盤 2 由 A 移至 B
盤 1 由 C 移至 B
盤 3 由 A 移至 C
盤 1 由 B 移至 A
盤 2 由 B 移至 C
盤 1 由 A 移至 C

 

 ①若是隻能移動到相鄰的  那麼n個圓盤須要  
  f(n)=(3^n)-1 次
②若是不加上只能移動到相鄰的限制的話     那麼n個圓盤須要  

  f(n)=(2^n)-1次

  1. public class Hanoi {  
  2.   
  3.     /** 
  4.      * @count記錄是第幾回移動 
  5.      */  
  6.     private static int count = 0;  
  7.   
  8.     /** 
  9.      * @Describe_將塔座x上按直徑大小自上而下編碼爲123...n個圓盤按規則一到塔座Z上_y作輔助塔座 
  10.      * @param n圓盤的格式 
  11.      * @param x起始圓盤的位置 
  12.      * @param y輔助塔座 
  13.      * @param z目標塔座 
  14.      */  
  15.     public static void hanoi(int n, char x, char y, char z) {  
  16.         if (n == 1) {  
  17.             move(x, 1, z);//  
  18.         } else {  
  19.             hanoi(n - 1, x, z, y);// 將前n-1個從x移動到y,z當輔助  
  20.             move(x, n, z);// 將變化爲n的圓盤從x移動到z  
  21.             hanoi(n - 1, y, x, z);// 再將前n-1個圓盤從y移動到z,x當輔助  
  22.         }  
  23.     }  
  24.   
  25.     /** 
  26.      * @Describe_移動操做_將編號爲n的圓盤從x移動到z 
  27.      * @param x 
  28.      * @param n 
  29.      * @param z 
  30.      */  
  31.     public static void move(char x, int n, char z) {  
  32.         System.out.println("第 " + (++count) + "次移動  :" + n + "號圓盤," + x + "-->"  
  33.                 + z);  
  34.     }  
  35.   
  36.     /** 
  37.      * @Describe_規則再次變化_再加上一個只能移動到相鄰的限制條件 
  38.      * @param n 
  39.      * @param x 
  40.      * @param y 
  41.      * @param z 
  42.      */  
  43.     public static void hanoi2(int n, char x, char y, char z) {  
  44.         if (n == 1) {  
  45.             move(x, 1, y);//  
  46.             move(y, 1, z);//  
  47.         } else {  
  48.             hanoi2(n - 1, x, y, z);// 將前n-1個從x移動到z,y當輔助  
  49.             move(x, n, y);// 將變化爲n的圓盤從x移動到y  
  50.             hanoi2(n - 1, z, y, x);// 再將前n-1個圓盤從z移動到x,y當輔助  
  51.             move(y, n, z);// 將變化爲n的圓盤從y移動到z  
  52.             hanoi2(n - 1, x, y, z);// 將前n-1個從x移動到z,y當輔助  
  53.         }  
  54.     }  
  55.   
  56.     public static void main(String[] args) {  
  57. //      Hanoi.hanoi(4, 'x', 'y', 'z');//------能夠移動到相鄰的或者不相鄰的  
  58. //      Hanoi.hanoi2(4, 'x', 'y', 'z');//-----只能移動到相鄰的  
  59.     }  

用棧實現:

package cglib;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Stack;  

 

public class StringNumber {
     //塔  
    class Tower<E> {  
       //塔編號  
       private int number;  
       //塔名稱  
       private String name;  
       //存放盤子的棧  
       private Stack<E> stack = new Stack<E>();  
         
       public Tower(int number,String name) {  
           this.number = number;  
           this.name = name;  
       }  
                
       public int getNumber() {  
           return number;  
       }  
   
       public String getName() {  
           return name;  
       }  
   
       public Stack<E> getStack() {  
           return stack;  
       }  
         
    }  
      
    //盤子  
    class Tray {  
       //盤子編號  
       private int number;  
       //盤子名稱  
       private String name;  
         
       public Tray(int number,String name) {  
           this.number = number;  
           this.name = name;  
       }  
         
       public int getNumber() {  
           return number;  
       }  
         
       public String getName() {  
           return name;  
       }  
         
       public String toString() {  
           return name;  
       }  
    }  
      
    public <T> void hanoi(int num,Tower<T> from,Tower<T> middle,  
           Tower<T> to) {  
       if(num == 1) {  
           move(from,middle,to);  
       } else {  
           //將num-1個盤子從from塔上移到middle塔上  
           hanoi(num-1,from,to,middle);  
           //將第num個盤子移到to塔上  
           move(from,middle,to);  
           //將num-1個盤子從middle塔上移到to塔上  
           hanoi(num-1,middle,from,to);  
       }  
    }  
      
    private <E> void move(Tower<E> from,Tower<E> middle ,Tower<E> to) {  
       E tray = from.getStack().pop();  
       to.getStack().push(tray);  
       StringBuilder sb = new StringBuilder();  
       sb.append("=====================Hanoi.move()======================\n")  
       .append(" Move tray : ").append(((Tray)tray).getName())  
       .append(" from ").append(from.getName()).append(" to ")  
       .append(to.getName()).append("\n ")  
       .append(from.getName()).append(":").append(format(from)).append(",")  
       .append(middle.getName()).append(":").append(format(middle)).append(",")  
       .append(to.getName()).append(":").append(format(to));  
       System.out.println(sb.toString());  
    }  
    
    private <E> String format(Tower<E> tower) {  
       Iterator<E> i = tower.getStack().iterator();  
       if (! i.hasNext())  
           return "[]";  
       StringBuilder sb = new StringBuilder();  
       sb.append('[');  
       while(i.hasNext()) {  
           sb.append(i.next().toString()).append(",");  
       }  
       sb.replace(sb.length()-1, sb.length(), "]");  
       return sb.toString();  
    }  
 
    public static void main(String[] args) {  
        StringNumber hanoi = new StringNumber();  
       Tower<Tray> from = hanoi.new Tower<Tray>(1, "1號塔");  
       Tower<Tray> middle = hanoi.new Tower<Tray>(2, "2號塔");  
       Tower<Tray> to = hanoi.new Tower<Tray>(3, "3號塔");  
       int num = 4;  
       for (int i = num; i >0; i--) {  
           Tray tray = hanoi.new Tray(i,i+"號盤子");  
           from.getStack().push(tray);  
       }  
       hanoi.hanoi(num, from, middle, to);  
    }
    
}
      


輸出:

=====================Hanoi.move()======================
 Move tray : 1號盤子 from 1號塔 to 2號塔
 1號塔:[4號盤子,3號盤子,2號盤子],3號塔:[],2號塔:[1號盤子]
=====================Hanoi.move()======================
 Move tray : 2號盤子 from 1號塔 to 3號塔
 1號塔:[4號盤子,3號盤子],2號塔:[1號盤子],3號塔:[2號盤子]
=====================Hanoi.move()======================
 Move tray : 1號盤子 from 2號塔 to 3號塔
 2號塔:[],1號塔:[4號盤子,3號盤子],3號塔:[2號盤子,1號盤子]
=====================Hanoi.move()======================
 Move tray : 3號盤子 from 1號塔 to 2號塔
 1號塔:[4號盤子],3號塔:[2號盤子,1號盤子],2號塔:[3號盤子]
=====================Hanoi.move()======================
 Move tray : 1號盤子 from 3號塔 to 1號塔
 3號塔:[2號盤子],2號塔:[3號盤子],1號塔:[4號盤子,1號盤子]
=====================Hanoi.move()======================
 Move tray : 2號盤子 from 3號塔 to 2號塔
 3號塔:[],1號塔:[4號盤子,1號盤子],2號塔:[3號盤子,2號盤子]
=====================Hanoi.move()======================
 Move tray : 1號盤子 from 1號塔 to 2號塔
 1號塔:[4號盤子],3號塔:[],2號塔:[3號盤子,2號盤子,1號盤子]
=====================Hanoi.move()======================
 Move tray : 4號盤子 from 1號塔 to 3號塔
 1號塔:[],2號塔:[3號盤子,2號盤子,1號盤子],3號塔:[4號盤子]
=====================Hanoi.move()======================
 Move tray : 1號盤子 from 2號塔 to 3號塔
 2號塔:[3號盤子,2號盤子],1號塔:[],3號塔:[4號盤子,1號盤子]
=====================Hanoi.move()======================
 Move tray : 2號盤子 from 2號塔 to 1號塔
 2號塔:[3號盤子],3號塔:[4號盤子,1號盤子],1號塔:[2號盤子]
=====================Hanoi.move()======================
 Move tray : 1號盤子 from 3號塔 to 1號塔
 3號塔:[4號盤子],2號塔:[3號盤子],1號塔:[2號盤子,1號盤子]
=====================Hanoi.move()======================
 Move tray : 3號盤子 from 2號塔 to 3號塔
 2號塔:[],1號塔:[2號盤子,1號盤子],3號塔:[4號盤子,3號盤子]
=====================Hanoi.move()======================
 Move tray : 1號盤子 from 1號塔 to 2號塔
 1號塔:[2號盤子],3號塔:[4號盤子,3號盤子],2號塔:[1號盤子]
=====================Hanoi.move()======================
 Move tray : 2號盤子 from 1號塔 to 3號塔
 1號塔:[],2號塔:[1號盤子],3號塔:[4號盤子,3號盤子,2號盤子]
=====================Hanoi.move()======================
 Move tray : 1號盤子 from 2號塔 to 3號塔
 2號塔:[],1號塔:[],3號塔:[4號盤子,3號盤子,2號盤子,1號盤子]

或者:

  1. import java.util.Stack;  
  2.   
  3. public class Demo {  
  4.   
  5.       public static void main(String[] args) {  
  6.              // TODO Auto-generated method stub  
  7.              int n=3;  
  8.              int disks=5;  
  9.             Tower[] towers= new Tower[ n];  
  10.              for( int i=0; i< n; i++){  
  11.                    towers[ i]= new Tower( i);  
  12.             }  
  13.               
  14.              for( int i= disks; i>=0; i--){  
  15.                    towers[0].add( i);  
  16.             }  
  17.              towers[0].moveDisks( disks, towers[2], towers[1]);  
  18.       }  
  19. }  
  20.   
  21. class Tower{  
  22.       public  Stack<Integer> disks;  
  23.       public int index;  
  24.         
  25.       public Tower(int index){  
  26.              disks= new Stack<Integer>();  
  27.              this. index= index;  
  28.       }  
  29.         
  30.       public int getIndex(){  
  31.              return this. index;  
  32.       }  
  33.         
  34.       public void add(int d){  
  35.              if(! disks.isEmpty()&& disks.peek()<= d)  
  36.                   System. out.println( "Error placing disk"+d);  
  37.              else  
  38.                    disks.push( d);  
  39.       }  
  40.         
  41.       //將orgin頂端的盤子移到destination  
  42.       public void movetoTop(Tower t){  
  43.              int top= disks.pop();  
  44.              t.add( top);  
  45.             System. out.println( "Move disk "+ top+ " from "+this.getIndex()+" to "+t.getIndex());  
  46.       }  
  47.         
  48.   
  49.       public void moveDisks( int n,Tower destination,Tower buffer){  
  50.              if( n>0){  
  51.                    //將頂端n-1個盤子從origin移到buffer  
  52.                   moveDisks( n-1, buffer, destination);  
  53.                    this.movetoTop( destination);  
  54.                    //將頂部n-1個盤子從buffer移到destination,將origin用做緩衝區  
  55.                    buffer.moveDisks( n-1, destination, this);  
  56.             }  
  57.       }  
  58. }
相關文章
相關標籤/搜索