快速排序

快速排序

  • 快速排序(Quicksort)是对冒泡排序的一种改进。

  • 快速排序由C. A. R.Hoare在1960年提出。

  • 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

  • 这是一种二分法思想,每次将整个无序序列一分为二,归位一个元素,对两个子序列采用同样的方式进行排序,直至子序列长度为1或0为止

快速排序的分治策略

  1. 分解: 将原序列a[s…t]分解成两个子序列a[s…i-1]和a[i+1…t],其中i=(s+t)/2
  2. 求解子问题: 若子序列的长度为0或1,则它是有序的,直接返回;否则递归求解各个子问题
  3. 合并: 由于整个序列存放在数组a中,排序过程是就地进行的,合并步骤不需要执行任何操作
    例图:
    在这里插入图片描述

示例程序

#include<iostream>
using namespace std;
void disp(int a[], int n)//输出a中元素
{
    for (int i=0; i < n; i++)
    {
        cout << a[i] << " ";
    }
}
int partiton(int a[], int s, int t)//划分算法
{
    int i = s, j = t; 
    int temp = a[s];//用序列的第一个元素作为基准
    while (i!= j)//两端交替向中间扫描,直至i=j为止
    {
        while (j > i && a[j] > temp)//从右向左扫描,直到第一个关键字小于temp的a[j]
            j--;
        a[i] = a[j];//将a[j]前移到a[i]的位置
         while (j > i && a[i] < temp)//从左向右扫描,直到第一个关键字大于temp的a[i]
            i++;
        a[j] = a[i];//将a[i]前移到a[j]的位置
    }
    a[i] = temp;
    return i;
}
void quick_sort(int a[], int s, int t)
{
    int i =0;
    if (s < t)//序列内至少存在两个元素的情况
    {
       i= partiton(a, s, t);
       quick_sort(a, s, i - 1);//向左边子序列递归排序
       quick_sort(a, i+1, t);//向右边子序列递归排序
    }
}
 int main()
{
    int n=10;
    int a[] = {2,5,1,7,10,6,9,4,3,8};
    cout << "排序前: " << endl;
    disp(a, n);
    cout << endl;
    quick_sort(a, 0, n-1);
    cout << "排序后: " << endl;
    disp(a, n);
    return 0;
}

运行结果展示

在这里插入图片描述

性能分析

  • 快速排序的一次划分算法从两头交替搜索,直到low和hight重合,因此其时间复杂度是O(n);而整个快速排序算法的时间复杂度与划分的趟数有关。

    理想的情况是,每次划分所选择的中间数恰好将当前序列几乎等分,经过log2n趟划分,便可得到长度为1的子表。这样,整个算法的时间复杂度为O(nlog2n)。

  • 最坏的情况是,每次所选的中间数是当前序列中的最大或最小元素,这使得每次划分所得的子表中一个为空表,另一子表的长度为原表的长度-1。这样,长度为n的数据表的快速排序需要经过n趟划分,使得整个排序算法的时间复杂度为O(n2)。

  • 为改善最坏情况下的时间性能,可采用其他方法选取中间数。通常采用“三者值取中”方法,即比较H->r[low].key、H->r[high].key与H->r[(low+high)/2].key,取三者中关键字为中值的元素为中间数。

  • 可以证明,快速排序的平均时间复杂度也是O(nlog2n)。因此,该排序方法被认为是目前最好的一种内部排序方法。

  • 从空间性能上看,尽管快速排序只需要一个元素的辅助空间,但快速排序需要一个栈空间来实现递归。最好的情况下,即快速排序的每一趟排序都将元素序列均匀地分割成长度相近的两个子表,所需栈的最大深度为log2(n+1);但最坏的情况下,栈的最大深度为n。这样,快速排序的空间复杂度为O(log2n)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值