快速排序递归与非递归代码实现与思考

18 篇文章 0 订阅
12 篇文章 1 订阅

有的时候也是不知道是为什么,就像高中数学王老师说的那样,熟能生巧,不理解的要学会接受,慢慢就会理解了。大二的时候进行数据结构课程设计,我选做的一个是将快速排序的递归程序修改成非递归的形式,我记得我当时修改了好久好几,总是觉得这个非递归不能办到,但是当时根本没有想到用栈的思想,现在又重新学习数据结构,知道了递归与栈之间的关系。在剑指offer这本书中读到递归的本质就是栈结构,所以将递归函数拆成非递归的最好用栈作为保存;

递归的代码更为简洁,但是当函数调用的层级很深的时候,有可能导致函数调用栈溢出,显示用栈基于循环实现的代码鲁棒性要好一些。(摘自剑指offer)

在快速排序中,若枢轴记录是从low指针开始,那么在第一次的循环中,必须要从high指针开始,因为这样就不会丢失数据。
首先介绍快速排序的思想:
1、设置两个指针分别是low,high指针,枢轴的关键字pivotkey。关键字pivotkey设置为low位置的记录。首先从high所指向位置起向前搜索找到第一个比pivotkey小的记录,此时low位置上的关键字被替换为high位置上的记录,然后再从low 位置开始向前搜索,找到第一个比pivotkey大的记录,此时high位置上的记录被替换为low位置上的记录,直至low=high,第一趟结束,此时将分割成两个小序列。
然后在对这些小序列分别进行步骤1,直至所有的小序列进行了步骤1,结束。

从快速排序的思想来看很明显是用递归的函数进行。
递归思想的代码如下:

#include<iostream>
#include<stack>
using namespace std;
int partation(int *L,int low,int high)
{

    int key=L[low];
    while(low<high)
    {
        while(low<high&&L[high]>=key)
            --high;
        L[low]=L[high];
        while(low<high&&L[low]<=key)
            ++low;
        L[high]=L[low];
    }
    L[low]=key;
    return low;

}
void Qsort(int *L,int low,int high)
{
    if(low<high)
    {
        int pivotloc=partation(L,low,high);
        Qsort(L,low,pivotloc-1);
        Qsort(L,pivotloc+1,high);
    }
}
nt main()
{
    int L[8]={49,38,65,97,76,13,27,49};
    Qsort(L,0,7);
    cout<<"利用递归的方法"<<endl;
    for(int i=0;i<8;i++)
        cout<<L[i]<<" ";
    cout<<endl;
    return 0;
}

然后是将递归的改成非递归的,然后是自己的代码写的还是有点冗长。
要有用栈存放low,high指针,所以最好有个结构体这样不容易混乱,结构体如下:

struct strLocation{
    int low;
    int high;
};
#include<iostream>
#include<stack>
using namespace std;
struct strLocation{
    int low;
    int high;
};
void partation2(int *L,int low,int high,stack<strLocation>&s)
{
    strLocation sLocL,sLocH;
    sLocL.low=low;
    sLocH.high=high;
    int key=L[low];
    while(low<high)
    {
        while(low<high&&L[high]>=key) --high;
        L[low]=L[high];
        while(low<high&&L[low]<=key)++low;
        L[high]=L[low];
    }
    L[low]=key;
    sLocH.low=low+1;
    sLocL.high=low-1;
    s.push(sLocL);
    s.push(sLocH);
}
void Qsort2(int *L,stack<strLocation>&s)
{
    while(!s.empty())
    {
        strLocation sLoc=s.top();
        s.pop();
        if(sLoc.low<sLoc.high)
            partation2(L,sLoc.low,sLoc.high,s);
    }
}
int main()
{

    int L1[8]={49,38,65,97,76,13,27,49};
    strLocation loc;
    loc.low=0;
    loc.high=7;
    stack<strLocation>s;
    s.push(loc);
    Qsort2(L1,s);
    cout<<"利用非递归的方法"<<endl;
    for(int i=0;i<8;i++)
        cout<<L1[i]<<" ";
    cout<<endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值