汉诺塔的非递归算法和递归算法--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; }
勤能补拙,熟能生巧