数据结构及算法——快速排序

2021/5/23 1:25:52

本文主要是介绍数据结构及算法——快速排序,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、关于快速排序的思想
快速排序是一种分治的思想,它通过一趟排序将待排序记录分割成独立的两个部分,其中的一部分关键字均比另一部分的关键字小,再分别对这两部分记录继续进行排序,以便达到整个序列有序的目的。

二、快速排序的代码(来源于大话数据结构)

#include <iostream>
#include <initializer_list>
#define MAXSIZE 10000
#define TRUE 1
#define FALSE 0
#define MAX_LENGTH_INSERT_SORT 7
typedef int Status;
struct SqList
{
    int r[MAXSIZE+1]= {0, 50, 10, 90, 30, 70, 40, 80, 60, 20};
    int length = 9;
};
void swap(SqList &L, int i, int j)
{
    int temp = L.r[i];
    L.r[i] = L.r[j];
    L.r[j] = temp;
}
//插入排序,用于在数据量小于某个值时的备选排序方法
void InsertSort(SqList &L)
{
    int i, j;
    for(i=2; i<=L.length; ++i)
    {
        if(L.r[i]<L.r[i-1])
        {
            L.r[0] = L.r[i];
            L.r[i] = L.r[i-1];
            for(j=i-2; L.r[j]>L.r[0]; --j)
                L.r[j+1] = L.r[j];    
            L.r[j+1] = L.r[0];
        }
    }
}
int Partition(SqList &L, int low, int high);
void QSort(SqList &L, int low, int high);
void QuickSort(SqList &L)
{
    QSort(L, 1, L.length);
}
void QSort(SqList &L, int low, int high)
{
    int pivot;
    if(L.length>MAX_LENGTH_INSERT_SORT)
    {
        while(low<high)
        {
            pivot = Partition(SqList &L, int low, int high);
            QSort(L, low, pivot-1); //对低子表递归排序
            //QSort(L, pivot+1, high);
            low = pivot+1; //尾递归,用于缩减递归堆栈深度
        }
    }
    else
    {
        InsertSort(L);
    }
}
int Partition(SqList &L, int low, int high)
{
    int pivotkey;
    //取左端、中间以及右端三个数中的中间值作为枢轴,避免出现极端分布的情况
    int m = (low+high)/2;
    if(L.r[low]>L.r[high])
        swap(L, low, high);
    if(L.r[m]>L.r[high]);
        swap(L, m, high);
    if(L.r[low]<L.r[m])
        swap(L, low, m);
    
    pivotkey = L.r[low];
    L.r[0] = pivotkey;
    while(low<high)
    {
       while(low<high && L.r[high]>=pivotkey)
           --high;
        L.r[low] = L.r[high];
        while(low<high && L.r[low]<=pivotkey)
            ++low;
        L.r[high] = L.r[low];
    }
    L.r[low] = L.r[0];
    return low;
}
int main()
{
    SqList L;
    QuickSort(L);
    for(int i=1; i<=L.length; ++i)
        std::cout << L.r[i] << " ";
}

三、关于优化后的代码
1、优化了Partition函数中枢轴的选取,采用三数取中的方法,避免因为开始选取的pivotkey值过大或者过小,而导致分割成的两部分元素个数相差过大,最后得到的递归树深度过深,从而使得时间复杂度和空间复杂度不够理想;
2、增加了直接插入排序作为备选,快速排序适合用于数据量较大的情况,而直接插入排序适合用于数据量较小的情况,故增加备选,以保证不同数据量的处理也能得到较好的性能;
3、优化了递归操作,将原本的QSort函数尾部的两次递归操作改变为尾递归优化,采用迭代而非递归,以便缩减堆栈深度,从而提高性能。(此处本人还存在疑惑,需要进一步学习)

四、关于时间复杂度和空间复杂度



这篇关于数据结构及算法——快速排序的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程