快速排序 递归转非递归

来源:互联网 发布:淘客小程序源码 编辑:程序博客网 时间:2024/05/18 11:46

递归程序巧妙地完成了回溯,那么如何将递归程序转换成非递归呢?

一般来说,递归的时候一定要分清哪些是可以直接由顶进行到底的(不需要回溯,即手头可以处理好的事件),哪些是需要回溯的(这部分可能根据回溯的顺序来排回溯的优先级,需要标注不同的状态,即待办事件),贴网上某人的博文,觉得总结的非常好。


通用法则为:


以下是如何把快速排序由递归程序转换为非递归程序:

递归的版本为:

void quicksort1(int a[],int l,int r){//标准版     int i=l,j=r,mid=a[(i+j)/2];     while(i<=j){                      while(a[i]>mid) i++;           while(a[j]<mid) j--;           if(i<=j){                 swap(a[i],a[j]);                 i++;j--;                            }     }       if( i<r )  quicksort1(a,i,r);     if( j>l )  quicksort1(a,l,j); }

一般来说,再次调用递归存在向栈push元素的可能,但并不是绝对的。。。要弄清当前事情全部处理完,就要回溯,会从栈顶取,因此区分当前事情是否处理完特别重要。。。贴一个错误的代码:

void quicksort2(int a[],int l,int r){//错误版本  stack<sValue> s; sValue sv; sv.first=l; sv.second=r; s.push(sv); while(!s.empty()){ sv=s.top(); s.pop(); int i=sv.first,j=sv.second,mid=a[(i+j)/2];    while(i<=j){                      while(a[i]>mid) i++;           while(a[j]<mid) j--;           if(i<=j){                 swap(a[i],a[j]);                 i++;j--;                            }    }   if(i<r){   sv.first=i; sv.second=r; s.push(sv);}if(j>l){   sv.first=l; sv.second=j; s.push(sv);} }}

再上一个正确的代码:


void quicksort3(int a[],int l,int r){     int i,j,mid; stack<sValue> s; sValue sv; while(l<r||!s.empty()){  while(l<r){ i=l;j=r;mid=a[(i+j)/2]; while(i<=j){             while(a[i]>mid) i++;   while(a[j]<mid) j--;   if(i<=j){ swap(a[i],a[j]); i++;j--;                    } }    l=i; r=r;  if(j>l){   sv.first=l; sv.second=j; s.push(sv); } } if(!s.empty()){  sv=s.top();  s.pop();  l=sv.first;  r=sv.second;  } }}







原创粉丝点击