汉诺塔的非递归算法和递归算法--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;
}

 

posted @ 2020-03-04 15:34  跃鱼  阅读(1632)  评论(0编辑  收藏  举报