漢諾塔的非遞歸算法和遞歸算法--C語言


題目:

即將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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM