递归转化为非递归的一般方法

转载:http://blog.csdn.net/biran007/article/details/4156351

面试中被问到,因为看过递归的汇编代码,知道是用栈来实现的,所写只能描述汇编使用栈的过程,不过也算是沾边了。如果真要实现转化,估计也是用栈来模拟。

———————————————————————————————————————————

递归的本质是通过栈来保存状态,然后再次调用自己进入新的状态,然后函数返回的时候回到上次保存的状态。

尾递归可以直接转化成循环,这里不多做分析

更一般的递归,想要转化为非递归,就需要模拟栈的行为。

 

首先需要自己建个栈。栈保存的东西是一个记录,包括所有局部变量的值,执行到的代码位置。

首先讲局部变量初始化位一开始的状态,然后进入一个循环

执行代码时,遇到递归,就制作状态压栈保存,然后更新局部变量进入下一层。

如果一个调用结束了,就要返回上层状态。直接讲栈里的记录弹出,拿来更新当前状态即可。

某个调用结束时如果栈为空则所有调用都结束,退出主循环。

下面的代码给出中序遍历的非递归实现:

 

[cpp]  view plain copy
  1. struct record{  
  2.     node* a;  
  3.     int state;  
  4.     record(node* a,int state):a(a),state(state){}  
  5. };  
  6. void non_recursive_inorder(){  
  7.     stack<record> s;  
  8.     node* cur=root;   //初始化状态   
  9.     int state=0;  
  10.     while(1){  
  11.         if(!cur){                //如果遇到null结点,返回上一层   
  12.             if(cur == root)break;//如果没有上一层,退出循环   
  13.             cur=s.top().a;  
  14.             state=s.top().state; //返回上层状态   
  15.             s.pop();  
  16.         }else if(state == 0){    //状态位0,执行第一个递归inorder(cur->left);   
  17.             s.push(record(cur,1));//保存本层状态   
  18.             cur=cur->left;        //更新到下层状态   
  19.             state=0;   
  20.         }else if(state == 1){      //状态为1,执行print和inorder(cur->right)  
  21.             printf("%d ",cur->x);  
  22.             s.push(record(cur,2));   //保存本层状态   
  23.             cur=cur->right;         //进入下层状态   
  24.             state=0;  
  25.         }else if(state == 2){      //状态2,函数结束,返回上层状态   
  26.             if(cur == root)break;  //初始结点的退出状态,遍历结束   
  27.             cur=s.top().a;         //返回上层状态   
  28.             state=s.top().state;  
  29.             s.pop();  
  30.         }  
  31.     }  
  32.     putchar(10);  
  33. }  
 

 

快速排序的非递归实现:

[cpp]  view plain copy
  1. #include<stdio.h>  
  2. int partition(int a[],int l,int r){  
  3.     int key=a[l],i=l,j=r;  
  4.     while(i<j){  
  5.         while(i<j && a[j] >= key)  
  6.             j--;  
  7.         if(i<j)  
  8.             a[i++]=a[j];  
  9.         while(i<j && a[i] <=key)  
  10.             i++;  
  11.         if(i<j)  
  12.             a[j--]=a[i];  
  13.     }  
  14.     a[i]=key;  
  15.     return i;  
  16. }  
  17. void qsort(int a[],int l,int r){  
  18. //boundary case  
  19.     if(l>=r)         
  20.         return;  
  21. //state 0  
  22.     int mid=partition(a,l,r);   
  23.     qsort(a,l,mid-1);  
  24. //state 1  
  25.     qsort(a,mid+1,r);           
  26. //state 2  
  27. }  
  28. struct recorc{  
  29.     int l,r,mid;   //local virables. a[] never changed, no need to save.  
  30.     int state;  
  31. }stack[100000];  
  32. void nun_recursive_qsort(int a[],int l,int r){  
  33.     int state=0,top=0;  
  34.     int mid;  
  35.     while(1){  
  36.         if(l>=r){ //boundary case, return previous level  
  37.             if(top == 0)  
  38.                 break;   //end of recursion  
  39.             top--;  
  40.             l=stack[top].l;        //end of function, update to previous state  
  41.             r=stack[top].r;  
  42.             mid=stack[top].mid;  
  43.             state=stack[top].state;  
  44.         }else if(state == 0){  
  45.             mid=partition(a,l,r);  
  46.             stack[top].l=l;         //recutsive call, push current state into stack  
  47.             stack[top].r=r;  
  48.             stack[top].mid=mid;  
  49.             stack[top].state=1;  
  50.             top++;  
  51.             r=mid-1;  
  52.             state=0;            //don't forget to update state value  
  53.         }else if(state == 1){  
  54.             stack[top].l=l;       
  55.             stack[top].r=r;         //recursive call, push current state into stack  
  56.             stack[top].mid=mid;  
  57.             stack[top].state=2;  
  58.             top++;  
  59.             l=mid+1;  
  60.             state=0;  
  61.         }else if(state == 2){  
  62.             if(top == 0)  
  63.                 break;   //end of recursion  
  64.             top--;  
  65.             l=stack[top].l;  
  66.             r=stack[top].r;  
  67.             mid=stack[top].mid;  
  68.             state=stack[top].state;  
  69.         }  
  70.     }  
  71. }  
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值