转载:http://blog.csdn.net/biran007/article/details/4156351
面试中被问到,因为看过递归的汇编代码,知道是用栈来实现的,所写只能描述汇编使用栈的过程,不过也算是沾边了。如果真要实现转化,估计也是用栈来模拟。
———————————————————————————————————————————
递归的本质是通过栈来保存状态,然后再次调用自己进入新的状态,然后函数返回的时候回到上次保存的状态。
尾递归可以直接转化成循环,这里不多做分析
更一般的递归,想要转化为非递归,就需要模拟栈的行为。
首先需要自己建个栈。栈保存的东西是一个记录,包括所有局部变量的值,执行到的代码位置。
首先讲局部变量初始化位一开始的状态,然后进入一个循环
执行代码时,遇到递归,就制作状态压栈保存,然后更新局部变量进入下一层。
如果一个调用结束了,就要返回上层状态。直接讲栈里的记录弹出,拿来更新当前状态即可。
某个调用结束时如果栈为空则所有调用都结束,退出主循环。
下面的代码给出中序遍历的非递归实现:
- struct record{
- node* a;
- int state;
- record(node* a,int state):a(a),state(state){}
- };
- void non_recursive_inorder(){
- stack<record> s;
- node* cur=root; //初始化状态
- int state=0;
- while(1){
- if(!cur){ //如果遇到null结点,返回上一层
- if(cur == root)break;//如果没有上一层,退出循环
- cur=s.top().a;
- state=s.top().state; //返回上层状态
- s.pop();
- }else if(state == 0){ //状态位0,执行第一个递归inorder(cur->left);
- s.push(record(cur,1));//保存本层状态
- cur=cur->left; //更新到下层状态
- state=0;
- }else if(state == 1){ //状态为1,执行print和inorder(cur->right)
- printf("%d ",cur->x);
- s.push(record(cur,2)); //保存本层状态
- cur=cur->right; //进入下层状态
- state=0;
- }else if(state == 2){ //状态2,函数结束,返回上层状态
- if(cur == root)break; //初始结点的退出状态,遍历结束
- cur=s.top().a; //返回上层状态
- state=s.top().state;
- s.pop();
- }
- }
- putchar(10);
- }
快速排序的非递归实现:
- #include<stdio.h>
- int partition(int a[],int l,int r){
- int key=a[l],i=l,j=r;
- while(i<j){
- while(i<j && a[j] >= key)
- j--;
- if(i<j)
- a[i++]=a[j];
- while(i<j && a[i] <=key)
- i++;
- if(i<j)
- a[j--]=a[i];
- }
- a[i]=key;
- return i;
- }
- void qsort(int a[],int l,int r){
- //boundary case
- if(l>=r)
- return;
- //state 0
- int mid=partition(a,l,r);
- qsort(a,l,mid-1);
- //state 1
- qsort(a,mid+1,r);
- //state 2
- }
- struct recorc{
- int l,r,mid; //local virables. a[] never changed, no need to save.
- int state;
- }stack[100000];
- void nun_recursive_qsort(int a[],int l,int r){
- int state=0,top=0;
- int mid;
- while(1){
- if(l>=r){ //boundary case, return previous level
- if(top == 0)
- break; //end of recursion
- top--;
- l=stack[top].l; //end of function, update to previous state
- r=stack[top].r;
- mid=stack[top].mid;
- state=stack[top].state;
- }else if(state == 0){
- mid=partition(a,l,r);
- stack[top].l=l; //recutsive call, push current state into stack
- stack[top].r=r;
- stack[top].mid=mid;
- stack[top].state=1;
- top++;
- r=mid-1;
- state=0; //don't forget to update state value
- }else if(state == 1){
- stack[top].l=l;
- stack[top].r=r; //recursive call, push current state into stack
- stack[top].mid=mid;
- stack[top].state=2;
- top++;
- l=mid+1;
- state=0;
- }else if(state == 2){
- if(top == 0)
- break; //end of recursion
- top--;
- l=stack[top].l;
- r=stack[top].r;
- mid=stack[top].mid;
- state=stack[top].state;
- }
- }
- }