快速排序的错误

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}


以上是关于快速排序的错误的主要内容,如果未能解决你的问题,请参考以下文章

C++ 快速排序段错误

显示错误输出的快速排序算法

交换算法引起的快速排序错误

在最佳情况下,由于堆栈溢出错误,快速排序算法失败 - C++

C快速排序(链表)分段错误

python 冒泡排序与快速排序 遇到的错误与问题