Java Quicksort值为什么/在哪里变化?

我现在在学校学习Java,我们最新的主题是Java中的排序算法.我想要了解的是快速排序.

为了理解该算法如何对数组中的数字进行排序,我决定在Eclipse调试器窗口中执行我的代码步骤.

现在有一个步骤,即使经历了数百次之后我也无法理解.

我的初始数组是[10,5,3,22,11,2]

当我浏览代码时,程序首先交换10和2,然后是5和3,然后是2和2.此时,i的值为1,j的值为-1.

现在我看到它的方式是有三个条件

> while(i< = j)返回false,因为i = 1且j = -1
> if(left< j)返回false,因为left = 0且j = -1
> if(i< right)其中也返回false,因为i = 1且right = 1
但令我惊讶的是,当程序在公共静态无效显示之前到达最后一个括号时,如果(i <右),程序将跳回到第40行.
但突然,右,i,j和枢轴的值分别从5,2,-1和3变为.

如果有人能解释为什么值会发生变化,我将非常感激.

我还添加了两张图片,显示了我在Eclipse窗口step I don’t understand上看到的内容

public class QSort {

    public static void quickSort(int[] arr, int left, int right){
        int i = left;
        int j = right;
        int temp;
        int pivot = arr[(left+right)/2];
        System.out.println("\n\nleft = " + left + "\tright = " + right);
        System.out.println("Pivot is: " + pivot + "(" +  (left+right)/2 + ")");
        while(i <= j){
            while(arr[i] < pivot){
                System.out.println("i is: " + arr[i] + "(" + i + ")");
                i++;
                System.out.println("i is: " + arr[i] + "(" + i + ")");
            }
            while(arr[j] > pivot){
                System.out.println("j is: "+ arr[j] + "(" + j + ")");
                j--;
                System.out.println("j is: "+ arr[j] + "(" + j + ")");
            }
            if(i <= j){
                System.out.println("i is: " + arr[i] + "(" + i + ")");
                System.out.println("j is: "+ arr[j] + "(" + j + ")");
                System.out.println("Swapped " + arr[i] + "(" + i + ")"+ " with " + arr[j] + "(" + j + ")");
                temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
                i++;
                j--;
                System.out.println("i is: (" + i + ")");
                System.out.println("j is: (" + j + ")");
                System.out.println("Pivot is: " + pivot + "(" +  (left+right)/2 + ")");
            }
        }
        if(left < j){
            System.out.println("j is: (" + j + ")");
            quickSort(arr, left, j);
        }
        if(i < right){
            System.out.println("i is: (" + i + ")");
            quickSort(arr, i, right);
        }
    }

    public static void display(int[] arr){
        if(arr.length > 0){
            System.out.print(arr[0]);
        }
        for(int i = 1; i < arr.length; i++){
            System.out.print(", " + arr[i]);
        }
    }

    public static void main(String[] args) {
        int[] data = new int[]{10,5,3,22,11,2};
        System.out.println("Before: ");
        display(data);
        quickSort(data, 0, data.length-1);
        System.out.println("\nAfter: ");
        display(data);
    }
}

非常感谢!

解决方法:

我认为你的问题是你不完全理解递归.至少从你对这个问题的描述中听起来就是这样.

无论如何,我试图通过记录所有变量来简单地遵循你的程序.希望这可以帮助:

arr                 left       right      i         j      pivot
-----------------   -------    --------   -------   -----  ----------
[10,5,3,22,11,2]    0          5         
                                          0         5      arr[2] = 3
[2,5,3,22,11,10]                          1         4
                                                    3
                                                    2
[2,3,5,22,11,10]                          2         1

while循环结束,因为i< = j现在为假(2> 1). 第一个条件是< j(0 <1)为真,所以你再次递归调用quicksort:quicksort(arr,0,1) - 这意味着你现在对已经排序的数组[2,3]进行排序,所以不会发生任何事情:

arr                 left       right      i         j      pivot
-----------------   -------    --------   -------   -----  ----------
[2,3,5,22,11,10]    0          1
                                          0         1      arr[0] = 2
                                                    0
[2,3,5,22,11,10]                          1         -1

while循环条件现在为false.第一个条件是< j也是假的(因为0> -1)并且第二个条件i <1.权利也是假的(因为1 == 1)所以这个电话结束了,你回到了原来的位置.是那样的吗?上表的第一个条件.变量和参数的状态现在是:

arr                 left       right      i         j      pivot
-----------------   -------    --------   -------   -----  ----------
[10,5,3,22,11,2]    0          5         2          1      3

检查第二个条件(因为它是下一行执行).它的值也是正确的,因为条件是i <1.对(2 <5).所以你现在再次递归快速输入:quicksort(arr,2,5) - 这意味着你现在对数组[3,22,11,10]进行排序:

arr                 left       right      i         j      pivot
-----------------   -------    --------   -------   -----  ----------
[2,3,5,22,11,10]         2          5         
                                          2         5      arr[3] = 22
                                          3
[2,3,5,10,11,22]                          4         4
                                          5

我> j现在我们退出while循环.

第一个条件是< j(2 <4)为真,所以我们称为quicksort(arr,2,4)以便对已经排序的[5,10,11]进行排序.我将跳过这部分,因为它根本不会改变数组. 当递归调用完成后,我们返回到原来的状态,现在将检查第二个条件.我<对(5 <5)是假的所以我们已经完成了. 原始的快速排序调用已完成,数组已排序.

上一篇:(转载)sqlmap用户手册详解


下一篇:写了12年JS也未必全了解的连续赋值运算