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個圓盤
}
}