【问题标题】:My quick sort implementation fails in some cases在某些情况下,我的快速排序实现失败
【发布时间】:2012-12-09 18:31:33
【问题描述】:

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

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

我可能犯了哪些错误?

【问题讨论】:

标签: c++ algorithm sorting quicksort


【解决方案1】:

好吧,问题出在这里:

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&gt;=a)的元素数量为N= b-a+1这一事实来解决。

在这里,我们有a=0b=right-1,因此是左子数组中的元素数,即sizeN=(right-1)-(0)+1=right

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

一直在发生:)

【讨论】:

  • 请您提供更多解释吗?
  • 你的意思是我必须通过 right 而不是 right-1 因为我从元素 1 开始?
  • @Eslam 已更新。阿米特的观点也值得注意。希望这会有所帮助。
【解决方案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] &lt; pivot(不是&lt;=)交换元素,如果@则减少right 987654326@(不是&gt;),类似于:

...
for(left=1,right=size-1;left<=right;){    //was size-1      
        if(a[left]>=pivot&&a[right]<pivot) { 
        //                         ^ note < not <=
        swap(left,right,a);
    }

    if(a[left]<pivot){left++;}
    if(a[right]>=pivot){right--;}
    //        ^ note >=
}
...

【讨论】:

  • 好的,这是一个很好的通知,但这不是上述问题的主要原因,谢谢
猜你喜欢
  • 2021-11-08
  • 1970-01-01
  • 2016-12-07
  • 1970-01-01
  • 2017-02-05
  • 1970-01-01
  • 2018-07-25
  • 1970-01-01
  • 2017-01-30
相关资源
最近更新 更多