[英]trouble-shooting my quicksort algorithm in java?
在解决我的quicksort
算法方法时出现问题,这个问题突然出现了;
考虑这个单独打印数组元素的简单示例:
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]);
}
}
总的来说,如果我打电话:
public static void main(String[] args) {
int[] data2 = new int[]{10,11,9,7,5};
print1(data2,0,data2.length);
System.out.println("___________");
print2(data2,0,data2.length-1);
}
两者都打印相同的内容,这是好的和好的; (注意,我将data2.length
和data2.length-1
作为参数传递给我的print1
和print2
方法,并且每个方法中的for-loop
相应地改变)
现在出现了快速排序制度的问题:考虑以下代码:
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;
}
在主;
public static void main(String[] args) {
//int[] data = new int[]{5,10,1,9,4,4,8,3,6,2,7,4};
int[] data = new int[]{3,4,1,2};
int[] data2 = new int[]{10,11,9,7,5};
System.out.print("Unsorted array data ");
display(data);
System.out.print("\nUnsorted array data2 :");
display(data2);
quickSort2(data, 0, data.length-1);
System.out.println("_____________");
quickSort2(data2,0,data2.length-1);
System.out.print("\nSorted array data: ");
display(data);
System.out.print("\nSorted array data2:");
display(data2);
}
工作得很好,很好; now如果我将调用更改为quickSort(data, 0, data.length)
并将for-loop
行(在代码中标记为*******
)更改for (int j = start+1;j<end;j++)
,我得到了完全不同的结果:即:前两个元素没有排序,但其余的元素被排序。 我明白了
Sorted array data: [2, 1, 3, 4]
Sorted array data2:[5, 9, 7, 10, 11]
我需要协助
快速浏览后,我认为有两个独立的错误 - 我在'main`中为每个quickSort2()
调用发现了一个错误。 由于您尝试排序的数组的性质,每个都被触发。
错误1:在您的主要第9行,您致电:
quickSort(data, 0, data.length);
所以,这是当你尝试quickSort()
{3,4,1,2}时。 在对quickSort2()
的第一次递归调用时发生错误,其参数的确切调用是
quickSort2({2,1,3,4}, 0, 1);
然后使用相同的参数调用partition()
partition({2,1,3,4}, 0, 1);
这是发生错误的地方。 看看你的for-loop
术语:
for (int j = start+1; j< end;j++)
j
将立即设置为1. End已等于1. 1 < 1
为false,因此循环永远不会触发。 解决方案:在为j
赋值时,只需删除+1。 你的循环将如下所示:
for (int j = start; j< end;j++)
i == j
的初始情况永远不会触发if-statement
所以我认为应该没问题。
错误2:在主要的第11行,你打电话:
quickSort2(data2,0,data2.length-1);
发生最终误差在同一个地方,因为它在该第一故障没有-在partition()
的第一递归调用期间quickSort2()
这最终具有以下参数:
partition({5,9,7,10,11}, 0, 2);
永远不会触发for-loop
的if-statement
,因为5是数据透视表,9和7都是较大的。 因此, i
返回零,这个数组的一半永远不会再次排序。 至于快速解决这个问题,我不能说有一个我能想到的。 你必须改变你的逻辑。
一些可能会帮助你的笔记/指针。
通常,Quicksort算法通常不会在数组中一直调用。 通常存在一种基本情况,其中排序切换到不同的算法。 例如,您只有5个对象可以对此调用进行排序。 那不是那么多,所以让我们切换到更简单的东西,比如插入排序。 尽管插入排序通常对大型集合的效率较低,但当您只需要重新排列5个或更少的对象时,这并不是什么大问题。
Quicksort实现通常也不会将集合中的第一个对象称为pivot。 这通常是一种糟糕的方法,如果您的列表已经排序或反向排序,该怎么办? 时间复杂度将非常平庸(O(N 2 ))。 相反,有一种称为“三个中位数”的方法,它不仅可以解决您的第二个错误,而且可以为您提供更好的时间复杂性。
在快速排序功能中调用第一个分区时,您还必须更改:
quickSort2(arr, i, part-1);
至
quickSort2(arr, i, part);
这是因为您没有使用最后一个索引(结束)。 因此,您的快速排序将不完整,因为您没有将最后一个元素放在枢轴之前,即使它的值低于数据透视表。
quickSort(data, 0, data.length-1);
//...
quickSort2(data2,0,data2.length-1);
我看到两个quickSort是不一样的,也许你有另一个名为quickSort的函数你忘了吗?或者只是写错了?
看看代码中添加了一些打印件并发现,经过修改后,在第二次运行你的pivot元素0时,显然是错误的。 我添加了一些数字作为未排序的数组数据:3 4 1 2 7 5 6
3 4 1 2 7 5 6
枢轴:2
2 1 3 4 7 5 6
pivot:0
2 1 3 4 7 5 6
2 1 3 4 7 5 6
2 1 3 4 7 5 6
枢轴:3
2 1 3 4 7 5 6
2 1 3 4 7 5 6
枢轴:6
2 1 3 4 6 5 7
枢轴:4
2 1 3 4 6 5 7
2 1 3 4 6 5 7
2 1 3 4 6 5 7
排序数组数据:2 1 3 4 6 5 7
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");
}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.