开始学习算法----快速排序
冒泡排序的复杂度正常来说是O(N^2),当然可以变成设立一个flag当一次循环结束没有发生交换就退出的加强版冒泡,但是似乎还是没有快排O(nlogn)来的快
快排是基于一种分治思想的排序,就是设立一个基准值,然后把比基准值小的放左边,比基准值大的放右边,
从 l---r 变成 l---index-1 index index+1-------r
然后继续在 l—index-1 和 index+1-------r中进行同样的操作,也就是分而治之的思想
具体代码如下:
void quick_sort(int l, int r, int a[])
{
//cout << l << " " << r << endl;
if (l < r)
{
int index = getindex(l, r, a);
quick_sort(l, index - 1, a);
quick_sort(index + 1, r, a);
}
}
剩下的就是如何实现设立一个基准值,然后把比基准值小的放左边,比基准值大的放右边
首先是从右边开始找,找到第一个比基准值小的值,把这个值赋给 a[l] 然后继续从左边找找到第一个大于基准值的数,将这个数赋给a[r]
其实就是类似于把a[r](小于基准值的值)移到左边,把a[l](大于基准值的值)移到右边
一直循环这个过程,直到l>=r
将此时的基准值赋给a[l]
这时就实现了比基准值小的放左边,比基准值大的放右边
int getindex(int l, int r, int a[])
{
/*
srand((unsigned)time(NULL));
int index=(rand()%(r-l))+l; //随机基准值
cout << "l-r:" << l << " " << r << " " << index << endl;
int tem = a[index];
*/
int tem = a[l];
while (l < r)
{
while (l < r && a[r] >= tem)
{
r--;
}
a[l] = a[r];
while (l < r && a[l] <= tem)
{
l++;
}
a[r] = a[l];
}
a[l] = tem;
return l;
}
这里我是选择将左边第一个数作为基准值,其实可以有更好的选择,比如选择三个数的中位数,或者直接选择随机数来当作基准数,这样可以大大加快速度
还有对于n<20时,选择插入排序会比快速排序快很多所以在分治递归时可以加一个条件,当r-l+1<20时直接选择用插入排序实现排序,不用继续递归,这样会快很多