快速排序

来源:互联网 发布:免费考勤软件 编辑:程序博客网 时间:2024/06/14 23:37

排序效率O(N*logN)

核心思想:分治法

排序过程:

1.当前待排序序列中取出一个数作为基准数。

具体操作:可以把第一个元素设为基准数

2.分区, 将比基准数大的数全放到它的右边,小于或等于它的数全放到它的左边。左右序列无需有序

具体操作:先从找一个小于基准数的数(因为基准数在左,查找应从右开始),再从找一个大于基准数的数,然后交换他们。之后继续查找,每次右侧先行;两个指针(姑且看做好了)相遇时,此时位置为基准数位置,与基准数交换;

其实就是右序列放大数,左序列放小数,左右移动,是移除不合格数据的过程

3.再对左右序列重复第二步,直到各区间只有一个数。

实际是对基准数的排序,将每个基准数放到自己合适的位置

相比于冒泡排序

交换的距离就不限于相邻。总的比较和交换次数就少了,速度提升。

最差时间复杂度和冒泡排序是一样的都是O(N2),平均时间复杂度为O(NlogN)。

置于为何右先行,是因为基准数在左,(基数在右,当然是左先行了)

这会影响最后基准数的位置:

基准数在左,每次第二步最后一步交换的必须小于基准数,右侧指针的任务就是找到小于基准数的内容;

左侧指针的任务就是找到大于基准数的内容,如果每次他先行,最后一步,找到的是大于基准数的内容,如何与基准数交换呢?

当然,最后一步之前采用左先行,最后一步右先行,也是可以的,但怎么确定哪次最后一步呢?太过麻烦


示例程序:

#include #include using namespace std;templateint  quick_sort(T *a,const int left,const int right)//此处用指针好一些,引用表示比较复杂{    int l=left;    int r=right;    T c,tem;    if(l>r)    {        return -1;    }    c=a[left];    while(l!=r)    {        while(c=a[l]&&l结果:



其实并没有完:

讨论基准数的选取:

首位数字作为基准数:如果输入随机,当然很好,当输入是预排序或反序,所有的元素都只会被划到一边去,这样很不好;

随机选取枢纽元:很安全,随机数生成花费较大

三数中值分割法:选取首尾元素a,b,及(a+b)/2位置的元素,将这三个数的中值元素,作为基准数

原创粉丝点击