CCI_Q3.4

本文参考该作者文章当作编程笔记:

作者:Hawstein
出处:http://hawstein.com/posts/ctci-solutions-contents.html

Q:

编程解决汉诺塔问题,使用数据结构栈.

思路:

1.递归:分成3个状态:

  1. 将src上的1~n-1个盘子借助dst移到bri上。
  2. 将src上的剩下的第n个盘子移动到dst上。
  3. 将bri上的1~n-1个盘子借助src移动到dst上。

参考:http://hawstein.com/posts/3.4.html

2.使用栈的非递归:

另一种汉诺塔移动方式:

  1. 3个柱子呈品字型放置,形成循环。如果盘子数目n是奇数,那么排放方式:A-》C-》B;如果是偶数,那么排列方式:A-》B-》C。
  2. 汉诺塔总共移动的步数是2n-1步。
  3. 将1号盘子由当前柱子(1号)移动到下一个柱子(2号)。
  4. 在1号柱子和3号柱子中选择一个非空的或者盘子比较小的柱子,将其上面的盘子移动到另外一个。
  5. 重复3和4,直到到达总步数。
  6. 成功。

参考:http://blog.minidx.com/2008/01/30/457.html

3.非递归

参考:http://www.zdyi.com/blog/hanoi/817

CODE:

1和2:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<math.h>
  4 #define less(A,B)(A<B)
  5 #define N 5
  6 #define Null 0
  7 void hanoi(int n,char src,char bri,char dst)
  8 {
  9     if(n==0)
 10         return;
 11     hanoi(n-1,src,dst,bri);
 12     printf("move %d from %c to %c\n",n,src,dst);
 13     hanoi(n-1,bri,src,dst);
 14 }
 15 typedef struct stack_h
 16 {
 17     int s[N];
 18     int cur;
 19     char name;
 20     //void (*stack_hPush)(int,struct stack_h*);
 21     //int (*stack_hPop)(int);
 22     //int (*stack_hTop)(int);
 23 }Stack_h;
 24 void stack_hPush(int item,Stack_h *h)
 25 {
 26     if(h->cur == (N-1))
 27         return;
 28     h->s[++h->cur]=item;
 29 }
 30 int stack_hPop(Stack_h *h)
 31 {
 32     if(h->cur==Null)
 33         return Null;
 34     return h->s[h->cur--];
 35 }
 36 int stack_hTop(Stack_h *h)
 37 {
 38     if(h->cur!=Null)
 39         return h->s[h->cur];
 40     return Null;
 41 }
 42 int main()
 43 {
 44     hanoi(4,'A','B','C');
 45     printf("*****************************\n");
 46     Stack_h h1={{Null,4,3,2,1},N-1,'A'},
 47             h2={{Null},Null,'B'},
 48             h3={{Null},Null,'C'};
 49     if((N-1)%2!=0)
 50     {
 51         h2.name='C';
 52         h3.name='B';
 53     }
 54     int step_num=pow(2,N-1)-1 , step_cout=0;
 55     while(step_cout<=step_num)
 56     {
 57         if(stack_hTop(&h1)==1)
 58         {
 59             stack_hPush(stack_hPop(&h1),&h2); 
 60             printf("move 1 from %c to %c\n",h1.name,h2.name);
 61             ++step_cout;
 62             if(step_cout==step_num)
 63                 break;
 64             if(stack_hTop(&h1)==Null)
 65             {
 66                 stack_hPush(stack_hPop(&h3),&h1); 
 67                 printf("move %d from %c to %c\n",
 68                         stack_hTop(&h1),h3.name,h1.name);
 69             }
 70             else if(stack_hTop(&h3)==Null)
 71             {
 72                 stack_hPush(stack_hPop(&h1),&h3);
 73                 printf("move %d from %c to %c\n",
 74                         stack_hTop(&h3),h1.name,h3.name);
 75             }
 76             else
 77             {
 78                 if(less(stack_hTop(&h1) , stack_hTop(&h3)))
 79                 {
 80                     stack_hPush(stack_hPop(&h1),&h3); 
 81                     printf("move %d from %c to %c\n",
 82                             stack_hTop(&h3),h1.name,h3.name);
 83                 }
 84                 else
 85                 {
 86                     stack_hPush(stack_hPop(&h3),&h1); 
 87                     printf("move %d from %c to %c\n",
 88                             stack_hTop(&h1),h3.name,h1.name);
 89                 }
 90             }
 91         }
 92         else if(stack_hTop(&h2)==1)
 93         {
 94             stack_hPush(stack_hPop(&h2),&h3); 
 95             printf("move 1 from %c to %c\n",h2.name,h3.name);
 96             ++step_cout;
 97             if(step_cout==step_num)
 98                 break;
 99             if(stack_hTop(&h1)==Null)
100             {
101                 stack_hPush(stack_hPop(&h2),&h1); 
102                 printf("move %d from %c to %c\n",
103                         stack_hTop(&h1),h2.name,h1.name);
104             }
105             else if(stack_hTop(&h2)==Null)
106             {
107                 stack_hPush(stack_hPop(&h1),&h2);
108                 printf("move %d from %c to %c\n",
109                         stack_hTop(&h2),h1.name,h2.name);
110             }
111             else
112             {
113                 if(less(stack_hTop(&h1) , stack_hTop(&h2)))
114                 {
115                     stack_hPush(stack_hPop(&h1),&h2); 
116                     printf("move %d from %c to %c\n",
117                             stack_hTop(&h2),h1.name,h2.name);
118                 }
119                 else
120                 {
121                     stack_hPush(stack_hPop(&h2),&h1); 
122                     printf("move %d from %c to %c\n",
123                             stack_hTop(&h1),h2.name,h1.name);
124                 }
125             }
126         }
127         else 
128         {
129             stack_hPush(stack_hPop(&h3),&h1); 
130             printf("move 1 from %c to %c\n",h3.name,h1.name);
131             ++step_cout;
132             if(step_cout==step_num)
133                 break;
134             if(stack_hTop(&h3)==Null)
135             {
136                 stack_hPush(stack_hPop(&h2),&h3); 
137                 printf("move %d from %c to %c\n",
138                         stack_hTop(&h3),h2.name,h3.name);
139             }
140             else if(stack_hTop(&h2)==Null)
141             {
142                 stack_hPush(stack_hPop(&h3),&h2);
143                 printf("move %d from %c to %c\n",
144                         stack_hTop(&h2),h3.name,h2.name);
145             }
146             else
147             {
148                 if(less(stack_hTop(&h3) , stack_hTop(&h2)))
149                 {
150                     stack_hPush(stack_hPop(&h3),&h2); 
151                     printf("move %d from %c to %c\n",
152                             stack_hTop(&h2),h3.name,h2.name);
153                 }
154                 else
155                 {
156                     stack_hPush(stack_hPop(&h2),&h3); 
157                     printf("move %d from %c to %c\n",
158                             stack_hTop(&h3),h2.name,h3.name);
159                 }
160             }
161         }
162         ++step_cout;
163     }
164 
165     return 0;
166 }
View Code

缺点:

使用栈的非递归2的程序写的很烂.有很多地方可以优化:例如可以把3个栈设为数组,通过不断加下标i,然后和3取余,确定柱子。还可以把重复的写成一个函数。等等。

 

posted @ 2014-03-14 21:10  哈士奇.银桑  阅读(156)  评论(0编辑  收藏  举报