排序效率O(N*logN)
核心思想:分治法
排序过程:
1.当前待排序序列中取出一个数作为基准数。
具体操作:可以把第一个元素设为基准数
2.分区, 将比基准数大的数全放到它的右边,小于或等于它的数全放到它的左边。左右序列无需有序
具体操作:先从右往左找一个小于基准数的数(因为基准数在左,查找应从右开始),再从左往右找一个大于基准数的数,然后交换他们。之后继续查找,每次右侧先行;两个指针(姑且看做好了)相遇时,此时位置为基准数位置,与基准数交换;
其实就是右序列放大数,左序列放小数,左右移动,是移除不合格数据的过程。
3.再对左右序列重复第二步,直到各区间只有一个数。
实际是对基准数的排序,将每个基准数放到自己合适的位置
相比于冒泡排序
交换的距离就不限于相邻。总的比较和交换次数就少了,速度提升。
最差时间复杂度和冒泡排序是一样的都是O(N2),平均时间复杂度为O(NlogN)。
置于为何右先行,是因为基准数在左,(基数在右,当然是左先行了)
这会影响最后基准数的位置:
基准数在左,每次第二步最后一步交换的必须小于基准数,右侧指针的任务就是找到小于基准数的内容;
左侧指针的任务就是找到大于基准数的内容,如果每次他先行,最后一步,找到的是大于基准数的内容,如何与基准数交换呢?当然,最后一步之前采用左先行,最后一步右先行,也是可以的,但怎么确定哪次最后一步呢?太过麻烦
示例程序:
#include
#include
using namespace std;
template
int 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
结果: ![](https://img-blog.csdn.net/20170616092633988?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWVlDUVdFUQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
其实并没有完:
讨论基准数的选取:
首位数字作为基准数:如果输入随机,当然很好,当输入是预排序或反序,所有的元素都只会被划到一边去,这样很不好;
随机选取枢纽元:很安全,随机数生成花费较大
三数中值分割法:选取首尾元素a,b,及(a+b)/2位置的元素,将这三个数的中值元素,作为基准数