在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语句,这是一个简单的一次性错误。它很容易修复,因为您需要担心的是循环的
。我认为您的快速排序无法真正进行比较。