挑战408——数据结构(8)——快速排序算法性能分析

先看看排序算法的C++代码实现:

#include <iostream>
#include <vector>
using namespace std;
/*函数原型*/
void sort(std::vector<int> &vec);
void quickSort(std::vector<int> & vec, int start, int finish);
int partition(std::vector<int> & vec, int start, int finish);
/*主函数*/
int main(){
    vector<int> vec;
    for (int i = 0; i < 8; i++){
        int n;
        cin >> n;
        vec.push_back(n);
    }
    sort(vec);
    for(int k = 0; k < vec.size();k++){
        cout << vec[k] <<" ";
    }
    return 0;
}

/*
 *函数: quickSort
 *对下标位置之间的元素进行排序,包括开始位置和结束位置。 
 *Quicksort算法开始于“分割”后向量
 *使得小于指定的枢轴元素的所有元素都显示在边界的左侧,
 *并且所有相等或更大的值都显示在右侧。
 *将子vector排序到边界的左侧和右侧确保整个vector被排序。
 */ 
void quickSort(vector<int> & vec, int start, int finish) {
    if (start >= finish) return; //下标相同,返回
    int boundary = partition(vec, start, finish); //找枢纽
    quickSort(vec, start, boundary - 1); //对vec的枢纽左边快速排序排序
    quickSort(vec, boundary + 1, finish);//对vec枢纽右边快速排序
}
/*
 *该函数重新排列vector的元素,使得小元素被分组在向量的左端,
 *而大元素分组在右端。通过比较每个元素与最初从vec [start]
 *获得的枢纽值来进行小和大的区别。当分区完成时,函数返回一
 *个边界索下标,使得0对于所有i <boundary,vec [i] <pivot,
 *对于vec [i] == pivot,i == boundary,对于i > pivot,
 *vec [i]> = pivot, 
 */ 
int partition(vector<int> & vec, int start, int finish){
    int pivot = vec[start];
    int lh = start + 1;
    int rh = finish;
    while(true){
        while(lh < rh && vec[rh] >= pivot) rh--;
        while(lh < rh && vec[lh] < pivot) lh++;
        if(lh == rh) break;
        int temp;
        int tmp = vec[lh];
        vec[lh] = vec[rh];
        vec[rh] = tmp;
    }
    if (vec[lh] >= pivot) return start;
    vec[start] = vec[lh];
    vec[lh] = pivot;
    return lh;
}
/*
 *用wrapper函数将函数调用变得更加简单*/
void sort(vector<int> &vec){
    quickSort(vec, 0, vec.size() - 1);
}

上述代码在VS2015编译成功:
在这里插入图片描述

性能分析

合并排序和Quicksort算法的实际运行时间的比较如下图所示。Quicksort的这种实现往往比合并排序的执行速度快几倍,这就是为什么程序员在实际中更频繁地使用它的原因之一。此外,两种算法的运行时间似乎都以大致相同的方式增长。
在这里插入图片描述
但是仅仅比较上图,却忽略了一点,只要Quicksort算法选择一个接近于向量中值的枢轴,分区步骤就会将vector划分成大致相等的部分。如果算法选择其枢轴值较差,则两个部分向量中的一个可能比另一个部分向量大得多,这违反了分治策略的原则。当要排序的vector中的数据是随机的时,Quicksort往往表现很好,平均情况下为O(N log N)。在最坏的情况下(比如这个vector已经排好了序 )性能退化为O(N^2)。
不过,尽管在最坏的情况下这种它的表现很差,但是Quicksort在实践中比大多数其他算法要快得多,目前它已经成为一般分类过程的标准选择。
我们可以使用几种方式来增加枢纽实际上接近vector中值的可能性。一个简单的方法是让Quicksort实现随机选择pivot元素。虽然随机过程仍然可能选择不良的枢轴值,但是在递归分解的每个级别都不太可能会发生相同的错误。此外,原始vector的分布总是随机的,给定任何输入,随机选择枢轴确保该向量的平均情况性能为O(N log N)。另一种方法是从vector中选择一些值,通常为三或五个,并选择这些值的中位数作为枢纽。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值