1. 程式人生 > >4.Hanoi塔遞迴演算法

4.Hanoi塔遞迴演算法

其實這個東西我有點看不懂,但覺得像我那麼沒基礎的人都選擇留下一部分知識點,肯定是考慮到它的實際效用相當高啦!!

輸入:圓盤數n,3根細杆——源杆A,過渡杆B,目標杆C

輸出:圓盤從源杆移動到目標杆過程的最少步驟序列

考慮方法,若只有一個盤子,則只要將其從源杆A移動到目標杆C就行。如果多於一個盤,先將源杆A上的前n-1個盤移動到過渡杆B上,再將留在源杆上的最大的盤移動到目標杆上,最後將過渡杆上的n-1個盤移動到目標杆上。這裡考慮下多次遞迴,就是每次盤子從大到小遞迴到最後一個盤子放上目標杆就行。

演算法虛擬碼:

1.    if n=1;

2.      then i<-PICK-TOP-DISK(current,A) //取出A杆上最小編號的盤

3.        current[i]<-C  //記錄每次i盤移動到哪個杆上

4.        count<-count+1  //記錄移動次數

5.        print "move",count,i,"disk:",A,"->",C

6.        return

7.    HANOI(n-1,A,C,B)     //將源杆A上的n-1個盤通過過渡杆C移動到B杆上

8.    current[n]<-C

9.    count<-count+1

10.  print "move",count,n,"disk:",A,“->”,C   //將第n個盤移動到C杆上

11.  HANOI(n-1,B,A,C)  //將源杆B上的n-1個盤通過過渡杆A移動到目標杆C上

其中PICK-TOP-DISK(current,X)   //其中X杆標號

1.    i<-1

2.    while i<=n and current[i]!=X  //盤從小編號到大編號,因為小號在上,檢查該編號盤是否在X杆上

3.      do i=i+1

4.    return i  //得到該編號X杆上最小編號i盤

c++:

hanoi.h

#define _hanoi_h

#include<stdio.h>

int pickTopDisk(char *current,char x){

int i=0;

while(current[i]!=x)

i++;

return i;

}

void hanoi(char *current,int n,char A,char B,char C){

static int count=0;

int i=0;

if(n==1){

i=pickTopDisk(current,A);

current[i]=C;

count++;

printf("move %d disk %d:%c->%c\n",count,i+1,A,C);

return;

}

hanoi(current,n-1,A,C,B);

current[n-1]=C;

count++;

printf("move %d disk %d:%c->%c\n",count,n,A,C);

hanoi(current,n-1,B,A,C);

}

main.cpp

#include<stdlib.h>

#include"hanoi.h"

int main(){

char current[]={'A','A','A','A'};

char A='A',B='B',C='C';

hanoi(current,4,A,B,C);

}

JAVA:

Hanoi.java

package test;

public class Hanoi {

public static int count;

public static void hanoi(char[] current,int n,char A,char B,char C) {

if(n==1) {

int i=0;

i=pickTopDisk(current,A);

current[i]=C;

count++;

System.out.println("move"+count+"disk"+n+":"+A+"->"+C);

return;

}

hanoi(current,n-1,A,C,B);

current[n-1]=C;

count++;

System.out.println("move"+count+"disk"+n+":"+A+"->"+C);

hanoi(current,n-1,B,A,C);

}

private static int pickTopDisk(char[] current,char x) {

int i=0;

while(current[i]!=x)

i++;

return i;

}

}

Test.java

package test;

//基本上hanoi只要改下下面的資料就能用

public class Test{

public static void main(String[] args){

Hanoi.count=0;

char[] current= {'A','A','A','A'};//只要將一開始圓盤位置陣列代入

char A='A',B='B',C='C';//開始時源杆,過渡杆,目標杆標號

Hanoi.hanoi(current,4,A,B,C);//其中4表示有4個圓盤

}

}