递归5--汉诺塔问题的栈实现

递归5--汉诺塔问题的栈实现

汉诺塔的递归解法:http://www.cnblogs.com/Renyi-Fan/p/6949515.html

一、心得

系统里面的递归就是靠栈来维护的,
区别我们普通栈的是维护递归的那个栈有返回地址
递归每深入一层,栈顶元素加一
递归每退出一层,栈顶元素减一
返回地址是执行完这一层,返回到上一层的地址

就是从栈里面取元素然后操作这个元素,如此循环往复,和队列操作几乎完全一样
然而这里用队列不得行,因为最前面的问题分解的子问题没有放在队列最前面

二、分析

三、代码及结果

 1 /*
 2 汉诺塔问题的栈实现
 3 f(n)=f(n-1)+1+f(n-1)
 4 Problem(n,'A','B','C')=Problem(n-1,'A','C','B')+Problem(1,'A','B','C')+Problem(n,'B','A','C') 
 5 队列不得行,因为最前面的问题分解的子问题没有放在最前面 
 6 */ 
 7 #include <iostream>
 8 #include <stack>
 9 using namespace std;
10 
11 struct Problem{
12     int n;
13     char src,mid,dest;
14     Problem(int nn,char s,char m,char d):n(nn),src(s),mid(m),dest(d){
15     }
16 };//一个Problem变量代表一个子问题,将src上的n个盘子
17 //一mid为中介,移动到dest
18 stack<Problem> stk;//用来模拟递归的栈,一个元素代表依次操作
19 //若有n个盘子,则栈的高度不超过n*3,因为出来一个数,进去三个数 
20 int main(){
21     int n;
22     cin>>n;
23     stk.push(Problem(n,'A','B','C'));//初始化第一轮操作 
24     while(!stk.empty()){//只要栈中还有数据,就接着处理 
25         Problem curPrb=stk.top();//取最上面的那个子问题,即当前问题
26         stk.pop();//因为要对刚刚那个子问题进行操作,所以让子元素直接出栈
27         if(curPrb.n==1) cout<<curPrb.src<<"->"<<curPrb.dest<<endl;
28         else{
29             //分解子问题,子问题要逆序放,因为栈是先进后出 
30             //先把分解得到的第三个子问题放入栈中
31             stk.push(Problem(curPrb.n-1,curPrb.mid,curPrb.src,curPrb.dest)); 
32             //再把第二个子问题放入栈中
33             stk.push(Problem(1,curPrb.src,curPrb.mid,curPrb.dest));
34             //最后放第一个子问题, 后放入栈的子问题先被处理
35             stk.push(Problem(curPrb.n-1,curPrb.src,curPrb.dest,curPrb.mid));
36              
37         } 
38     } 
39     return 0;
40 } 

原文地址:https://www.cnblogs.com/Renyi-Fan/p/6955068.html