快速排序的错误
Posted 码农在途
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速排序的错误相关的知识,希望对你有一定的参考价值。
纠正上上周(2018 年 12 月 23 日),所发的快速排序代码,对于三数取中值没有将中值点放在右边第二位,导致结果出错这里纠正一下。
快速排序
思想:在无序数组中找到分区点 ,左边都为小于等于分区点的值,右边都为大于等于分区点的值。将整个数组分成 N 个这样的数组,当最后分区小于三个元素时说明排序完成。
快速排序的算法好坏很大程度上取决于 『 分区点 』,本文代码采用的是 『 三数中值分割法 』,即取数组最左端最右端以及数组中间三个数的中间数为分区点,减少采用左右端点碰到极端顺序的出现的最坏情况( 当选取左右端点,碰到数据有序,从大到小或是从小到大的情况 ,算法时间复杂度就会变成最坏时间复杂度)。
当需要排序的数组长度小与 3 时采用插入排序,否则继续递归使用快速排序
1void quickSort(int *arry, int left, int right)
2{
3 int i, j, pivot;
4 if (left + 3 <= right)
5 {
6 i = left; j = right - 1; pivot = median(arry, left, right);
7 while (true)
8 {
9 while (arry[++i] < pivot);
10 while (arry[--j] > pivot);
11 if (i < j)
12 Swap(arry + i, arry + j);
13 else
14 break;
15 }
16 Swap(arry+i,arry+right-1);//将分界点放到中间
17 quickSort(arry, left, i - 1);
18 quickSort(arry, i + 1,right);
19 }
20 else
21 {
22 insertSort(arry+left,right-left+1);
23 }
24}
通过 『 三数中值法 』优化分区点
1int median(int* arry,int left,int right)
2{
3 int temp = left+(right-left)/2;
4 if (arry[left]>arry[right])
5 Swap(arry+left,arry+right);
6 if (arry[left]>arry[temp])
7 Swap(arry+left,arry+temp);
8 if (arry[temp] > arry[right])
9 Swap(arry+temp,arry+right);
10 Swap(arry+temp,arry+right-1);//将中间值放到右边第二个数,确保右边扫描过的数都大于 中间值
11 return arry[right - 1];
12}
采用插入排序而非冒泡排序等,在极端情况下的优化时间复杂度
1void Swap(int *num1,int *num2)
2{
3 int temp = *num1;
4 *num1 = *num2;
5 *num2 = temp;
6}
7void insertSort(int *arry,int length)
8{
9 int i=0, j=0,temp=0;
10 for (; i < length - 1; i++)
11 {
12 temp = arry[i + 1];//temp 为 arry[i] 的下一个数
13 for (j = i; j >= 0;) //按从小到大的顺序排序,先从最大的开始比较,将新加入元素放入合适位置
14 {
15 if (temp < arry[j])
16 {
17 Swap(arry+j,arry+j+1);// 将较大值放到末尾
18 j--;
19 }
20 else
21 break;
22 }
23 }
24}
以上是关于快速排序的错误的主要内容,如果未能解决你的问题,请参考以下文章