简体   繁体   English

奇怪的选择排序行为

[英]Strange selection sort behavior

I have tried to attempt implementing my own Selection Sort code. 我试图尝试实现自己的选择排序代码。 So far, the code sorta works... It just behaves strangely. 到目前为止,代码sorta起作用了……它的行为很奇怪。

class HelloWorld {
 public static void main(String[] args) {
    long startTime = System.currentTimeMillis();

    int a[] = {
        3,7,8,4,22,13,9,5,10
    };

    int max_pos = a.length-1;
    int counter = 0;
    int min_sort = 0;
    int j = -1;
    int min_pos = 0;
    int i=0;

    while (j < max_pos) {
        i=j+1;
        min_sort = a[i];
        // traverse trough unsorted portion
        while (i < max_pos) {
            i++;
            if (min_sort > a[i]) {
                min_sort  = a[i]; // minimum unsorted
                min_pos = i;
            }
        }

        // sorted portion
        j++;
        a[min_pos] = a[j];
        a[j] = min_sort ;
        for(int x=0; x < a.length; x++) {
            System.out.print(a[x] + ", ");
        }
        System.out.print("\t\t");
        System.out.println("i: " + i + " j: " + j + " min pos: " + min_pos + " min val: "+ min_sort);
    }
  }
 }

I have tried tracing it, and the output goes like this: 我尝试跟踪它,并且输出如下所示:

3, 7, 8, 4, 22, 13, 9, 5, 10,           i: 8 j: 0 min pos: 0 min val: 3          
3, 4, 8, 7, 22, 13, 9, 5, 10,           i: 8 j: 1 min pos: 3 min val: 4          
3, 4, 5, 7, 22, 13, 9, 8, 10,           i: 8 j: 2 min pos: 7 min val: 5          
3, 4, 5, 7, 22, 13, 9, 7, 10,           i: 8 j: 3 min pos: 7 min val: 7          
3, 4, 5, 7, 7, 13, 9, 22, 10,           i: 8 j: 4 min pos: 7 min val: 7          
3, 4, 5, 7, 7, 9, 13, 22, 10,           i: 8 j: 5 min pos: 6 min val: 9          
3, 4, 5, 7, 7, 9, 10, 22, 13,           i: 8 j: 6 min pos: 8 min val: 10         
3, 4, 5, 7, 7, 9, 10, 13, 22,           i: 8 j: 7 min pos: 8 min val: 13         
3, 4, 5, 7, 7, 9, 10, 13, 22,           i: 8 j: 8 min pos: 8 min val: 22

Since this is almost certainly an educational process on your part (real code would just call Arrays.sort() ), I won't give a direct answer initially. 由于这几乎可以肯定是您的教育过程(实际代码只会调用Arrays.sort() ),因此我一开始不会给出直接答案。

Instead, you should notice that it's the line where j == 3 which is when the 8 appears to magically transmogrify into a 7 . 相反,您应该注意到,这是j == 3的行,这是8似乎神奇地转化为7

So you should start to hone your debugging skills. 因此,您应该开始磨练调试技巧。 Run the code through a debugger up to the end of the output of the previous line, then single step every single instruction. 通过调试器运行代码,直到上一行输出的末尾,然后对每条指令执行单步操作。 At some point, you'll see the 7 become an 8 and that's the code you need to focus on. 在某个时候,您会看到7变成8这就是您需要关注的代码。

Once you've done that, you'll hopefully be able to tell what the problem is. 完成此操作后,您将有望分辨出问题所在。 However, if you're still stuck (make sure you try first, or you'll never improve), see below. 但是,如果您仍然遇到困难(请确保先尝试 ,否则将永远无法改善),请参见下文。 t--- t--

This is a detailed analysis of your problem. 这是对您的问题的详细分析。 You are storing information about the minimum (both the value min_sort and its position min_pos ) each time you find an element that's smaller than the first one you set up in each iteration of the outer loop: 每当您发现一个小于外部循环的每次迭代中设置的第一个元素的元素时,您都将存储有关最小值的信息(值min_sort及其位置min_pos

if (min_sort > a[i]) {
    min_sort  = a[i]; // minimum unsorted
    min_pos = i;
}

Now that's a good way to do it, and these two pieces of information are later used in the swapping process (1) : 现在这是一个很好的方法,稍后将在交换过程中使用这两条信息(1)

j++;
a[min_pos] = a[j];
a[j] = min_sort;

However, what of the case where you don't find an element smaller than the first one set up, such as the following where when position 3 holds the value 7 and all values beyond that are greater than 7 : 但是,在找不到小于第一个元素的元素的情况下,例如以下情况,其中当位置3保留值7且所有超出该值的元素都大于7

3, 4, 5, 7, 22, 13, 9, 8, 10
         ^

In that case, the body of the if statement will never be run and the initial conditions from the start of the iteration will still apply: 在这种情况下, if语句的主体将永远不会运行,并且从迭代开始的初始条件仍然适用:

i=j+1;
min_sort = a[i];

Notice anything missing there? 注意到那里缺少什么吗? Such as, let's see, the position being set to something? 例如,让我们看看将位置设置为某些值吗?

Bingo! 答对了! If the first element being checked in an iteration is already in its correct position, min_pos will remain set to whatever it was previously and, when you swap, that's not going to be pretty. 如果在迭代中检查的第一个元素已经在正确的位置,则min_pos将保持设置为先前的值,并且当您进行交换时,这不会很漂亮。 You can fix that by changing the code immediately inside the outer while loop to be: 您可以通过将外部while循环内的代码立即更改为以下内容来解决此问题:

i = j + 1;
min_pos = i;          // add this line
min_sort = a[i];

and you'll see the greatly improved (ie, correct) output of: 并且您将看到大大改进(即正确)的输出:

3, 7, 8, 4, 22, 13, 9, 5, 10, i: 8 j: 0 min pos: 0 min val: 3
3, 4, 8, 7, 22, 13, 9, 5, 10, i: 8 j: 1 min pos: 3 min val: 4
3, 4, 5, 7, 22, 13, 9, 8, 10, i: 8 j: 2 min pos: 7 min val: 5
3, 4, 5, 7, 22, 13, 9, 8, 10, i: 8 j: 3 min pos: 3 min val: 7
3, 4, 5, 7, 8, 13, 9, 22, 10, i: 8 j: 4 min pos: 7 min val: 8
3, 4, 5, 7, 8, 9, 13, 22, 10, i: 8 j: 5 min pos: 6 min val: 9
3, 4, 5, 7, 8, 9, 10, 22, 13, i: 8 j: 6 min pos: 8 min val: 10
3, 4, 5, 7, 8, 9, 10, 13, 22, i: 8 j: 7 min pos: 8 min val: 13
3, 4, 5, 7, 8, 9, 10, 13, 22, i: 8 j: 8 min pos: 8 min val: 22

(1) The swap, by the way, is not necessary when the smallest remaining value is already in the correct position, though it does no harm. (1)顺便说一句,当最小的剩余值已经在正确的位置时,则不需要交换,尽管这没有害处。 If you wanted to avoid the unnecessary swap, you could use: 如果要避免不必要的交换,可以使用:

j++;
if (min_pos != j) {
    a[min_pos] = a[j];
    a[j] = min_sort ;
}

However, as stated, it's not a problem to do the swap so it's really up to you. 但是,如前所述,进行交换不是问题,所以这完全取决于您。

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

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