題目:
即將N個盤子從起始柱(標記為“a”)通過借助柱(標記為“b”)移動到目標柱(標記為“c”)
解法一、非遞歸算法
所有的漢諾塔移動可以總結為重復的兩步,我們假設現在最小的圓盤在a柱子上,柱子為a,b,c
第一步:將最小圓盤移動到下一個柱子上,也就是b
第二步:對a柱子和c柱子進行頂上最小的元素進行判斷,把小一點的那個圓盤移動到大一點的那個圓盤(有空則摞在空柱子上)。
重復上述兩步,直到兩根柱子均空結束。
注意:這樣得到的最后的答案不一定是摞在c上,如果N是偶數將摞在b上,所以如果N是偶數我們就令第二個柱子為c,第三個柱子為b,這樣就一定最后是摞在c上的。
1 #include <stdio.h> 2 #include <malloc.h> 3 #define ElemType char 4 #define ERROR -1 5 #define max 1000 6 typedef enum {false,true 7 } bool; 8 typedef struct { 9 char *Data; 10 int Top; 11 int MaxSize; 12 }*Stack; 13 Stack a[4]; 14 char c[4]= {'q','a','b','c'};//柱子編號從1開始 15 Stack CreateStack(int maxsize) { 16 Stack S=(Stack)malloc(sizeof(Stack)); 17 S->Data=(ElemType*)malloc(sizeof(ElemType)*maxsize); 18 S->MaxSize=maxsize; 19 S->Top=-1; 20 return S; 21 } 22 bool IsEmpty(Stack S) { 23 if(S->Top==-1) 24 return true; 25 return false; 26 } 27 bool IsFull(Stack S) { 28 if(S->Top==S->MaxSize-1) 29 return true; 30 return false; 31 } 32 bool Push(Stack S,ElemType X) { 33 if(IsFull(S)) 34 return false; 35 S->Data[++S->Top]=X; 36 return true; 37 } 38 ElemType Pop(Stack S) { 39 if(IsEmpty(S)) 40 return ERROR; 41 return S->Data[S->Top--]; 42 } 43 ElemType GetTop(Stack S) { 44 return S->Data[S->Top]; 45 } 46 47 bool move(int before,int after) { 48 if(IsEmpty(a[before])) 49 return false; 50 if(!IsEmpty(a[after])) { 51 if(GetTop(a[after])<GetTop(a[before])) 52 return false; 53 } 54 Push(a[after],Pop(a[before])); 55 printf("%c -> %c\n",c[before],c[after]); 56 } 57 int main() { 58 int n; 59 scanf("%d",&n); 60 int i; 61 for(i=0; i<4; i++) { 62 a[i]=CreateStack(max); 63 } 64 if(n%2==1) { 65 c[2]='c'; 66 c[3]='b'; 67 } 68 for(i=0; i<n; i++) { 69 Push(a[1],n-i); 70 } 71 int cnt=0; 72 while(++cnt) { 73 move((cnt-1)%3+1,(cnt)%3+1); 74 if(!move((cnt-1)%3+1,(cnt+1)%3+1)&&!move((cnt+1)%3+1,(cnt-1)%3+1)) 75 break; 76 } 77 }
解法二、遞歸算法
第1步:將n-1個盤從a->b; hannoi(n-1,a,b,c)
第2步:將第n個盤從a->c;(遞歸出口) printf("a -> c")
第3步:再將n-1個盤從b->c;hannoi(n-1,b,c,a)
注意傳入參數后 a='a',b='c',c='b';
#include <stdio.h> int hanoi(int n,char a,char b,char c) { if(n>0) { hanoi(n-1,a,c,b); printf("%c -> %c\n",a,b); hanoi(n-1,c,b,a); } } int main() { int n; scanf("%d",&n); hanoi(n,'a','c','b'); return 0; }