[英]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.