在java中解决快速排序算法的问题?

在java中解决快速排序算法的问题?,java,algorithm,for-loop,quicksort,indexoutofboundsexception,Java,Algorithm,For Loop,Quicksort,Indexoutofboundsexception,当我对快速排序算法的方法进行故障排除时,出现了这个问题 考虑以下单独打印数组元素的简单示例: public static void print1(int[] arr, int start, int end){ for (int k = start; k<end;k++){ System.out.println(arr[k]); } } public static void print2(int[] arr, int s

当我对
快速排序算法的方法进行故障排除时,出现了这个问题

考虑以下单独打印数组元素的简单示例:

public static void print1(int[] arr, int start, int end){
        for (int k = start; k<end;k++){
            System.out.println(arr[k]);
        }
    }
    public static void print2(int[] arr, int start, int end){
        for (int k=start; k<=end;k++){
            System.out.println(arr[k]);
        }
    }
两者都打印相同的内容,这是很好的; (注意,我将
data2.length
data2.length-1
作为参数传递给我的
print1
print2
方法,并且每个方法中的
for循环
相应地改变)

现在出现了快速排序机制的问题: 考虑这个代码:

public static void quickSort2(int[] arr, int i, int j){
        if (i<j){
            int part =partition(arr, i, j);
            quickSort2(arr, i, part-1);
            quickSort2(arr, part+1, j); 
        }
    }

public static int partition(int[] arr, int start, int end){
        int pivot = arr[start];
        int i = start;
        for (int j = start+1;j<=end;j++){ // ******
            if (arr[j]<pivot){
                    i++;
                    int temp=arr[i];
                    arr[i]=arr[j];
                    arr[j]=temp;
            }
        }
        arr[start]=arr[i];
        arr[i]=pivot;
        return i;
    }
作品精美;
现在,如果我将调用更改为
quickSort(data,0,data.length)
,并将
for循环
行(在代码中用
*********
标记)更改为
for(int j=start+1;j快速查看之后,我认为有两个单独的错误-我为
quickSort2()中的每一个都发现了一个
在“main”中调用。每个调用都是由于您试图排序的数组的性质而触发的

错误1:在main的第9行,您调用:

quickSort(data, 0, data.length);
quickSort2(data2,0,data2.length-1);
因此,这是当您尝试
quickSort()
{3,4,1,2}时发生的错误。错误发生在对
quickSort2()
的第一次递归调用上,其参数为

quickSort2({2,1,3,4}, 0, 1);
然后用相同的参数调用
partition()

partition({2,1,3,4}, 0, 1);
这就是错误发生的地方。请查看循环的
术语:

 for (int j = start+1; j< end;j++)
初始情况下,
i==j
is将永远不会触发
if语句,因此我认为应该可以

错误2:在main的第11行,您调用:

quickSort(data, 0, data.length);
quickSort2(data2,0,data2.length-1);
最终的错误发生在与第一个bug相同的地方,即在第一次递归调用
quickSort2()
partition()
中出现的错误,该错误最终具有以下参数:

partition({5,9,7,10,11}, 0, 2);
for循环
中的
if语句
永远不会触发,因为5是轴,9和7都较大。因此
i
返回为零,数组的这一半永远不会再次排序。 至于这个问题的快速解决方案,我不能说有一个是我能想到的。你必须改变你的逻辑

一些可以帮助您解决问题的注释/指针。

一般来说,快速排序算法通常不会在整个数组中被调用。通常有一种基本情况,排序会切换到另一种算法。例如,在这个调用中,只剩下5个对象可以排序。这并不多,所以让我们切换到更简单的方法,例如插入排序。即使插入排序在大型集合上通常效率较低,当您只需要重新排列5个或更少的对象时,这并不是什么大问题

快速排序实现通常也不会将集合中的第一个对象称为pivot。这通常是一种不好的方法,因为如果列表已经排序或反向排序,则会发生什么情况?时间复杂度相当一般(O(N2))。相反,有一种称为“三的中间值”的方法,这不仅可以解决您的第二个bug,还可以提高时间复杂度

quickSort(data, 0, data.length-1);
//...
quickSort2(data2,0,data2.length-1);

我发现这两个快速排序不一样,可能是您忘记了另一个名为quickSort的函数?或者只是写错了?

查看了添加了一些打印的代码,发现在第二次运行修改后,您的pivot元素0明显出了问题。我添加了一些数字作为 未排序的数组数据: 3 4 1 2 7 5 6

3 4 1 2 7 5 6

枢轴:2
2134756

枢轴:0
2134756

2134756

2134756

枢轴:3
2134756

2134756

枢轴:6
2134657

package quicksort;

public class Quicksort {

public static void main(String[] args) {
        int[] data = new int[]{3,4,1,2,7,5,6};
       System.out.print("Unsorted array data:\n");
       display(data);
       quickSort2(data,0,data.length);
       System.out.print("\nSorted array data:\n");
       display(data);
}

public static void quickSort2(int[] arr, int i, int j){
    display(arr);
    if (i<j){
        int part =partition(arr, i, j);
        quickSort2(arr, i, part-1);
        quickSort2(arr, part+1, j); 
    }
}

public static int partition(int[] arr, int start, int end){
    int pivot = arr[start];
    //System.out.println(pivot);
    int i = start;
    int temp;
    for (int j = start;j<end;j++){ // ******
        if (arr[j]<pivot){
                i++;
                temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
        }
    }
    arr[start]=arr[i];
    arr[i]=pivot;
    System.out.println("pivot: "+i);
    return i;
}

public static void display(int[] data){
for(int i=0;i<data.length;i++){
    System.out.print(data[i]+" ");
}
System.out.println("\n");
}}
枢轴:4
2134657

package quicksort;

public class Quicksort {

public static void main(String[] args) {
        int[] data = new int[]{3,4,1,2,7,5,6};
       System.out.print("Unsorted array data:\n");
       display(data);
       quickSort2(data,0,data.length);
       System.out.print("\nSorted array data:\n");
       display(data);
}

public static void quickSort2(int[] arr, int i, int j){
    display(arr);
    if (i<j){
        int part =partition(arr, i, j);
        quickSort2(arr, i, part-1);
        quickSort2(arr, part+1, j); 
    }
}

public static int partition(int[] arr, int start, int end){
    int pivot = arr[start];
    //System.out.println(pivot);
    int i = start;
    int temp;
    for (int j = start;j<end;j++){ // ******
        if (arr[j]<pivot){
                i++;
                temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
        }
    }
    arr[start]=arr[i];
    arr[i]=pivot;
    System.out.println("pivot: "+i);
    return i;
}

public static void display(int[] data){
for(int i=0;i<data.length;i++){
    System.out.print(data[i]+" ");
}
System.out.println("\n");
}}
2134657

package quicksort;

public class Quicksort {

public static void main(String[] args) {
        int[] data = new int[]{3,4,1,2,7,5,6};
       System.out.print("Unsorted array data:\n");
       display(data);
       quickSort2(data,0,data.length);
       System.out.print("\nSorted array data:\n");
       display(data);
}

public static void quickSort2(int[] arr, int i, int j){
    display(arr);
    if (i<j){
        int part =partition(arr, i, j);
        quickSort2(arr, i, part-1);
        quickSort2(arr, part+1, j); 
    }
}

public static int partition(int[] arr, int start, int end){
    int pivot = arr[start];
    //System.out.println(pivot);
    int i = start;
    int temp;
    for (int j = start;j<end;j++){ // ******
        if (arr[j]<pivot){
                i++;
                temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
        }
    }
    arr[start]=arr[i];
    arr[i]=pivot;
    System.out.println("pivot: "+i);
    return i;
}

public static void display(int[] data){
for(int i=0;i<data.length;i++){
    System.out.print(data[i]+" ");
}
System.out.println("\n");
}}
2134657

package quicksort;

public class Quicksort {

public static void main(String[] args) {
        int[] data = new int[]{3,4,1,2,7,5,6};
       System.out.print("Unsorted array data:\n");
       display(data);
       quickSort2(data,0,data.length);
       System.out.print("\nSorted array data:\n");
       display(data);
}

public static void quickSort2(int[] arr, int i, int j){
    display(arr);
    if (i<j){
        int part =partition(arr, i, j);
        quickSort2(arr, i, part-1);
        quickSort2(arr, part+1, j); 
    }
}

public static int partition(int[] arr, int start, int end){
    int pivot = arr[start];
    //System.out.println(pivot);
    int i = start;
    int temp;
    for (int j = start;j<end;j++){ // ******
        if (arr[j]<pivot){
                i++;
                temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
        }
    }
    arr[start]=arr[i];
    arr[i]=pivot;
    System.out.println("pivot: "+i);
    return i;
}

public static void display(int[] data){
for(int i=0;i<data.length;i++){
    System.out.print(data[i]+" ");
}
System.out.println("\n");
}}
已排序数组数据: 2134657

package quicksort;

public class Quicksort {

public static void main(String[] args) {
        int[] data = new int[]{3,4,1,2,7,5,6};
       System.out.print("Unsorted array data:\n");
       display(data);
       quickSort2(data,0,data.length);
       System.out.print("\nSorted array data:\n");
       display(data);
}

public static void quickSort2(int[] arr, int i, int j){
    display(arr);
    if (i<j){
        int part =partition(arr, i, j);
        quickSort2(arr, i, part-1);
        quickSort2(arr, part+1, j); 
    }
}

public static int partition(int[] arr, int start, int end){
    int pivot = arr[start];
    //System.out.println(pivot);
    int i = start;
    int temp;
    for (int j = start;j<end;j++){ // ******
        if (arr[j]<pivot){
                i++;
                temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
        }
    }
    arr[start]=arr[i];
    arr[i]=pivot;
    System.out.println("pivot: "+i);
    return i;
}

public static void display(int[] data){
for(int i=0;i<data.length;i++){
    System.out.print(data[i]+" ");
}
System.out.println("\n");
}}
包快速排序;
公共类快速排序{
公共静态void main(字符串[]args){
int[]数据=新的int[]{3,4,1,2,7,5,6};
System.out.print(“未排序的数组数据:\n”);
显示(数据);
quickSort2(数据,0,数据长度);
System.out.print(“\n已删除的数组数据:\n”);
显示(数据);
}
公共静态void quickSort2(int[]arr,int i,int j){
显示(arr);

如果(i在调用快速排序函数中的第一个分区时,您还必须更改:

quickSort2(arr, i, part-1);


这是因为您没有使用最后一个索引(结束)。因此,您的快速排序将不完整,因为即使最后一个元素的值低于pivot,您也没有将其放在pivot之前。

很抱歉,出现了一些键入错误,我在代码中修复了它们并编辑了问题。很抱歉,出现了一些键入错误,我在代码中修复了它们并编辑了问题。请注意代码这样可以很好地工作,并给出正确的输出。但是当我更改调用方式时,它会出错。我确实理解循环从未触发。但是我的问题是,为什么使用
数据调用的这种更改。length-1
会产生很大的不同。我会说,在这个算法中没有简单的方法来创建等价物。我可能是错的。但我这么说因为对于第一个例子,对于print语句,这是一个简单的一次性错误。它很容易修复,因为您需要担心的是循环的
。我认为您的快速排序无法真正进行比较。