快速排序

快速排序使用了分治思想。
对典型的子数组A[p..r]进行快速排序的三步分治过程:
分解: 数组A[p..r]被划分为两个(可能为空)子数组A[p..q-1]和A[q+1..r],使得子数组A[p..q-1]的所有元素都不大于A[q],数组A[q+1,r]的元素都大于A[q]中的每个元素。这里需要计算下标q。
解决: 通过递归进行快速排序,对子数组A[p..q-1]和A[q+1,r]都进行快速排序。
合并: 对子数组都是进行原址排序的,因此不需要合并。

//第p到r的元素是要进行快速排序的元素
void quickSort(vector<int> &heap, int p, int r) {
    if (p < r) {
        int i = partition(heap, p, r);
        quickSort(heap, p, i - 1);
        quickSort(heap, i + 1, r);
    }
}
//以heap[r]为主元。通过函数中的for循环,一直保持p<=k<=i,heap[k]<=x
//i+1<=k<=j-1,heap[k]>x
//j<=k<=r-1,是还未进行比较的元素
//经过所有循环最终结果是 heap[p..i]元素都小于或等于x,heap[i+2..r]元素都大于x.
int partition(vector<int> &heap, int p, int r)
{
    int x = heap[r];
    int i = p - 1;
    int positive = 0;
    //这个循环是为了判断子数组heap[p..r]的元素是不是全部相同,如果都相同则返回(p+r)/2
    for (int j = p; j <= r; j++) {
        if (heap[j] != x)
        {
            positive = 1;
            break;
        }
    }
    if (positive == 0) return (p + r) / 2;
    for (int j = p; j < r; j++) {
        if (heap[j] <= x) {
            i = i + 1;
            swap(heap[i], heap[j]);
        }
    }
    swap(heap[i + 1], heap[r]);
    return i+1;
}

快速排序的性能
最坏情况的划分。当划分产生的两个子问题分别包含了n-1个元素和0个元素时,最坏的情况发生。 时间复杂度为O(n^2)
平均情况下,时间复杂度为O(n);任何一种常数比例的划分都会产生深度为O(lgn)的递归树,其中每一层的时间代价都是O(n)。因此只要划分是常数比例的,算法的运行时间总是O(nlgn)。
当好和差的划分交替出现时,快速排序的时间复杂度与全是好的划分时是一样的,仍是O(nlgn)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值