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

原创 2016年05月30日 17:11:44

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

相关文章推荐

快速排序实现之递归与非递归

一、算法思想:   快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。设当前待排序的无序...

快速排序递归与非递归

快速排序思想:以升序为例;在要排序的序列中选一个基准,使它左边的数都比它小,右边的数都比它大。具体步骤:1、区间选一个key,可以选区间右边界的那个数;2、让begin从区间左边界开始往后找大于key...

快速排序之递归与非递归

Following is a typical recursive implementation of Quick Sort that uses last element as pivot. /* ...

快速排序 的原理及其java实现(递归与非递归)

快速排序 的原理及其java实现(递归与非递归)

汉诺塔(必须经过中间柱子)递归与非递归详解与代码实现

首先介绍一下汉诺塔最初始的规则:有三根相邻的柱子,标号为A,B,C,A柱子从上到下按照金字塔状叠放着n个不同大小的圆盘,现在把所有的盘子一个一个移动到柱子B上,并且每次移动同一根柱子上都不能出现大盘子...

用非递归的方法实现快速排序

用递归的方法实现的算法一般都可以用

[算法入门]快速排序非递归方法(Java实现),大家一起来找茬啊~

基础总结一下,快速排序的步骤: 1、找到一个key值(就是数组第一个值),先从右到左找,找到一个比它小的值,记录下标。 2、然后从左往右找,找到一个比它大的值,记录下标。 3、交换找到的两个数字...

快速排序非递归版实现

今天研究了一下快速排序如何用非递归算法解决。下面代码,自认为非常简洁,通过简单测试没有发现任何问题,供大家参考。 本程序利用了“栈” 代码如下: #include #include #inclu...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)