简体   繁体   English

快速排序出错(添加了一些重复项)

[英]Quicksort went wrong (added some duplicates)

I'm new to sorting algorithms and can't seem to figure out what went wrong.我是排序算法的新手,似乎无法弄清楚出了什么问题。 With an unsorted array of int [] uArr = {5,2, 10, 7, 6, 0, 8, 1, 9}, i'm given 0,1,2,5,5,6,8,10 (the nine in the org. array was replaced with a duplicate 5 and the 7 was lost).对于 int [] uArr = {5,2, 10, 7, 6, 0, 8, 1, 9} 的未排序数组,我得到 0,1,2,5,5,6,8,10 ( org. 数组中的 9 被重复的 5 替换,并且 7 丢失了)。 If I add duplicates to the array, I get more duplicates after the array is sorted and a few more missing numbers.如果我将重复项添加到数组中,则在对数组进行排序后会得到更多重复项以及更多丢失的数字。

 public static void main(String args[]){
     int [] uArr = {5,2, 10, 7, 6, 0, 8, 1, 9};

     qSort(uArr, 0, 8);
     
 }

 public static void qSort(int [] A, int low, int high){
    
    if (low < high){
   int pivotL = partition(A, low, high);
   qSort(A, low, pivotL);
 qSort(A, pivotL+1, high);
    }       
}
public static int partition(int [] arr, int low, int high){
 int pivot = arr[low];
 int leftwall = low;
 for (int i = low + 1; i < high; i++){
if (arr[i] < pivot){
 int temp = arr[i];
 arr[i] = arr[leftwall];
arr[leftwall] = temp;
leftwall += 1;

}  
}

int temp2 = pivot;
pivot = arr[leftwall];
arr[leftwall] = temp2;
return leftwall;
}
}

So one thing you should seriously do is start writing documentation.因此,您应该认真做的一件事是开始编写文档。 Even though this is a small program, you seem to have forgotten what you were doing as you were writing the code.尽管这是一个小程序,但您在编写代码时似乎已经忘记了自己在做什么。

For example, there are 9 elements in the array, and you pass in the offsets to sort, inclusive, as 0 through 8:例如,数组中有 9 个元素,您传入要排序的偏移量,包括 0 到 8:

  qSort( uArr, 0, 8 );

But then in the partition routine you only sort elements less than the high value:但是然后在分区例程中,您只对小于high值的元素进行排序:

 for( int i = low + 1; i < high; i++ ) {

And unlike you the last value in the array, 9, is never touched for me and never sorted.与您不同,数组中的最后一个值 9 对我来说从未被触及,也从未排序。 So that's an issue.所以这是个问题。 Figure out if you want your indexes to be inclusive or not.弄清楚您是否希望索引具有包容性。 For me writing documentation as I go helps me keep these ideas straight.对我来说,写文档 go 帮助我保持这些想法。

I'm still looking for other problems like the duplication.我仍在寻找其他问题,例如重复。

Update: I'm going to just post these as I figure them out, as a sort of stream-of-consciousness of how I look for problems.更新:我将在我弄清楚它们时发布这些,作为我如何寻找问题的一种意识流。 One thing I was taught early on is that adding print statements to your code can be faster than using a debugger.我很早就被教导的一件事是,将打印语句添加到代码中比使用调试器要快。 So (after re-formatting your code, because the formatting you posted was frankly crap) I added this:所以(在重新格式化你的代码之后,因为你发布的格式坦率地说是废话)我添加了这个:

 public static void qSort( int[] A, int low, int high ) {
    System.out.println( Arrays.toString( A ) + " low=" + low + " high=" + high );

And got this output:并得到了这个 output:

run:
[5, 2, 10, 7, 6, 0, 8, 1, 9] low=0 high=8
[2, 0, 1, 5, 6, 5, 8, 10, 9] low=0 high=3
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=0 high=2
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=0 high=0
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=1 high=2
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=1 high=1
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=2 high=2
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=3 high=3
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=4 high=8
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=4 high=5
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=4 high=4
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=5 high=5
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=6 high=8
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=6 high=6
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=7 high=8
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=7 high=7
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=8 high=8
[0, 1, 2, 5, 5, 6, 8, 10, 9]
BUILD SUCCESSFUL (total time: 0 seconds)

I did have to stare at the output for a while, but what I noticed next was two things.我确实不得不盯着 output 看了一会儿,但接下来我注意到的是两件事。 The 5 is duplicated almost immediately, and the 5 is also the first element, which means it's going to be chosen by your partition code as the pivot. 5 几乎立即被复制,并且 5 也是第一个元素,这意味着它将被您的partition代码选择为 pivot。 So it looks as though you have problems re-merging the pivot with the array.所以看起来你在将 pivot 与阵列重新合并时遇到了问题。

Update 2: OK found another problem.更新 2:OK 发现另一个问题。 This one I found by writing your array out by hand and walking through each value of i and leftwall as it makes the first partition.这个我是通过手工写出你的数组并遍历ileftwall的每个值来找到的,因为它是第一个分区。 Problem here:这里的问题:

When the pivot, 5, encounters the element 0 in the array, the rest of the array has not been sorted.当pivot,5遇到数组中的元素0时,数组的rest还没有被排序。 The 10 , 7 , 6 , etc. are not less than the pivot and have not be touched. 10等不小于7 6没摸过。 So when you make the swap, you sawp this:所以当你进行交换时,你会看到这个:

[2, 5, 10, 7, 6, 0, 8, 1, 9]

for this:为了这:

[2, 5, 0, 7, 6, 5, 8, 1, 9]

This is because leftwall was 1 (it had been swapped with the 2 but not any other number, so it only had been incremented once) and there's the duplication and losing numbers too.这是因为leftwall为 1(它已与2交换,但没有与任何其他数字交换,所以它只增加了一次)并且也有重复和丢失的数字。 I'm going to stop there because you have some pretty big problems.我将停在那里,因为你有一些非常大的问题。

What you need to do in this case is swap the 10 , not the pivot, with the 0 .在这种情况下,您需要做的是用0交换10 ,而不是 pivot 。 This is going to require one additional pointer at least.这至少需要一个额外的指针。 Quicksort algorithms need to find the lowest and highest in the array and have two loops inside the outer for loop.快速排序算法需要找到数组中的最低值和最高值,并且在外部for循环中有两个循环。 What you have here is a kind of weird recursive insert sort.您在这里拥有的是一种奇怪的递归插入排序。 You'll need to think a bit more how to do this, but two more loops, nest inside the first, will be required.您需要多考虑一下如何做到这一点,但是需要另外两个循环,嵌套在第一个循环中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM