簡體   English   中英

在java中解決我的快速排序算法?

[英]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.lengthdata2.length-1作為參數傳遞給我的print1print2方法,並且每個方法中的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-loopif-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM