在某些情况下,我的快速排序实现失败

时间:2012-12-09 18:31:33

标签: c++ algorithm sorting quicksort

我已经实现了一个快速排序算法,但是当我测试它时,我注意到当输入数组在第一个元素中有最大元素时这会失败(这是我获得数据的元素)。这是我的代码:

void partition(int *a,int size){
    if(size<=1){return;}
    int pivot=a[0];
    int left=0,right=0;
    for(left=1,right=size-1;left<=right;){    //was size-1
        if(a[left]>=pivot&&a[right]<=pivot) {
            swap(left,right,a);
        }

        if(a[left]<pivot){left++;}
        if(a[right]>pivot){right--;}
    }
    swap(0,right,a);
    partition(a,right-1);
    partition(&(a[right+1]),size-right-1);
}

一些失败的样本:

I/P 245  111  32    4
O/P 4   111  32  245     `

I/P 154   11   43  3  7
O/P   7   11   43  3  154

我犯过哪些错误?

2 个答案:

答案 0 :(得分:2)

在分区函数中,您缺少数组中有一个元素的情况。

假设arr = { 5, 5, 1 , 1, 5, }

pivot = 5
iter1:
left=1, arr[left]=5 ; right=4,arr[right]=5
(swapping)
not increasing left nor decreasing right - since 5 < 5 == false ; 5 > 5 == false

下一次迭代,相同的场景将重演,你实际上会得到一个无限循环。

处理它的一种方法是确定“大”部分还将增加所有正好是枢轴的元素,并在arr[right] < pivot(不是<=)时交换元素,并减少{ {1}} right(不是arr[right] >= pivot),例如:

>

答案 1 :(得分:2)

嗯,问题出在这里:

partition(a,right-1); // <- It's partition(array,size)!

将其更改为

partition(a,right);

它会起作用。我想你知道原因 要使分区功能正常工作,您必须提供两件事:

1)要处理的阵列。
  2)它拥有的元素数量,大小。

问题在于对左子阵列进行分区的第一次递归调用:partition(a,right-1)

参数2 size被错误地指定为right-1,而实际上是right

这可以通过使用从索引ab(包括b>=a)的数组中的元素数量为N= b-a+1的事实来解决这个问题。

此处,我们有a=0b=right-1,因此左子数组中的元素数量为sizeN = (right-1)-(0)+1 = { {1}}。

因此要正常工作,您必须像right一样调用它。 左子数组在partition(a,right);结束,但它有right-1 = right-1+1个元素。

一直发生:)