快速排序

简介:

针对冒泡排序我们进行一次优化,就引进了快速排序在此基础上进行优化

基本思想:

  • 任取一个记录(如第一个)作为 枢轴或支点,设其关键字为pivotkey。

  • 在一趟排序后,所有比它小的记录一律前放,比它大的记录一律后放,形成左右两个子表,将枢轴放在分界处的位置;

  • 然后,分别对各子表重新选择枢轴,并依此规则调整,直到每个子表的元素只剩一个,排序完成。

具体操作

(1)附设两个指针low和high,初始时分别指向表的上限和下限,设枢轴记录的关键字为pivotkey(第一趟时,low=1,high=L.length)

(2)从表的最右侧位置,依次向左搜索找到第一个关键字小于pivotkey的记录和枢轴记录交换。具体操作:当

low<high时,若high所指纪录的关键字大于等于pivotkey,则向左移动指针high(即–high),否则high所指纪

录与枢轴纪录交换。

(3)然后再从表的左侧位置,依次向右搜索第一个关键字大于pivotkey的记录和枢轴记录交换。具体操作:当low<high时,若low所指记录的关键字小等于pivotkey,则向右移动指针low(即++low),否则low所指记录与枢轴记录交换。

(4)重复(2)(3)步骤,直到low和high相等为止,此时low或high的位置即为枢轴在此趟排序中的最终位置,原表被分成两个子表。

这里写图片描述
这里写图片描述

  • 每一趟的子表的形成是采用从两头向中间交替式逼近法;

  • 由于每趟中对各子表的操作都相似,可采用递归算法。

    int Partition(SqList &L,int low,int high)
    {
        L.r[0]=L.r[low];
        pivotkey=L.r[low].Key;
        while(low<high)
    {
         while(low<high&&L.r[high].Key>=pivotkey)--high;
         L.r[low]=L.r[high];
     while(low<high&&L.r[low].key<pivotkey)++low;
    }
     L.r[high]=L.r[low];
         return low;
    }
    void QSort(SqList &L,int low,int high)
    {
        if(low<high)
    {
        pivotloc=Partition(L,low,high);
        QSort(L,low,pivotloc-1);
        QSort(L,pivotloc+1,high);
    }
    }
        void QuickSort()
        {
        QSort(L,1,L.length);
    }
    

算法分析可以证明,平均计算时间是O(nlog2n)。

实验结果证明:就平均计算时间而言,快速排序是我们所学习的所有内排序方法中最好的一个。

快速排序是递归的,需要有一个栈存放每层递归调用时参数(新的low和high)。

最大递归调用层次数与递归树的深度一致,因此要求存储开销为O(log2n)。

最好:划分后,左侧右侧子序列的长度相同

最坏:从小到大排好序,递归树成单支树,每次划分只得到一个比上一次少一个对象的子序列,必须经过n-1
趟才能把所有对象定位,而且第i趟需要经过n-i次关键码比较才能找到第i个对象的安放位置

时间效率:O(nlog2n)—-每趟确定的元素呈指数增加

空间效率:O(log2n)—–递归要用到栈空间

稳定性:不稳定—–可选任一元素为支点。

目录
相关文章
快速排序(超超详细,因为自己也不是很会)
快速排序(超超详细,因为自己也不是很会)
|
5月前
快速排序
快速排序
21 0
|
5月前
|
算法
快速排序(三)——hoare法
快速排序(三)——hoare法
63 1
|
10月前
|
C++
C++快速排序
C++快速排序
54 1
|
人工智能 搜索推荐
【快速排序】
【快速排序】
|
算法 搜索推荐
快速排序到底有多快
快速排序到底有多快
78 0
|
机器学习/深度学习
785. 快速排序
785. 快速排序
65 0
【1. 快速排序】
思路: > 1. 确定分界点:q[l] , q[(1 + r)/2] , q[r] , 随机 > 2. 调整区间的范围:使得在`分界点左侧是数都<= x`, `分界点右侧的数都>= x `(`重点处理`)
86 0
【1. 快速排序】