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

本文探讨了快速排序算法的递归与非递归实现方式,并通过实例对比了两种方法的具体实现过程。文章详细介绍了递归的简洁性和非递归方法使用栈结构来避免函数调用栈溢出的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有的时候也是不知道是为什么,就像高中数学王老师说的那样,熟能生巧,不理解的要学会接受,慢慢就会理解了。大二的时候进行数据结构课程设计,我选做的一个是将快速排序的递归程序修改成非递归的形式,我记得我当时修改了好久好几,总是觉得这个非递归不能办到,但是当时根本没有想到用栈的思想,现在又重新学习数据结构,知道了递归与栈之间的关系。在剑指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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值