1. 程式人生 > >經典排序演算法之--快速排序

經典排序演算法之--快速排序

快速排序是一種高效但不穩的排序演算法,不穩性取決於比較基數的選擇帶有隨機性,其排序原理應用百度百科如下:

設要排序的陣列是A[0]……A[N-1],首先任意選取一個數據(通常選用陣列的第一個數)作為關鍵資料,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序。值得注意的是,快速排序不是一種穩定的排序演算法,也就是說,多個相同的值的相對位置也許會在演算法結束時產生變動。

一趟快速排序的演算法是:

1)設定兩個變數i、j,排序開始的時候:i=0,j=N-1;

2)以第一個陣列元素作為關鍵資料,賦值給key,即key=A[0];

3)從j開始向前搜尋,即由後開始向前搜尋(j--),找到第一個小於key

的值A[j],將A[j]和A[i]互換;

4)從i開始向後搜尋,即由前開始向後搜尋(i++),找到第一個大於key的A[i],將A[i]和A[j]互換;

5)重複第3、4步,直到i=j; (3,4步中,沒找到符合條件的值,即3中A[j]不小於key,4中A[i]不大於key的時候改變j、i的值,使得j=j-1,i=i+1,直至找到為止。找到符合條件的值,進行交換的時候i, j指標位置不變。另外,i==j這一過程一定正好是i+或j-完成的時候,此時令迴圈結束)。

排序演示

編輯

示例

假設使用者輸入瞭如下陣列:

下標

0

1

2

3

4

5

資料

6

2

7

3

8

9

建立變數i=0(指向第一個資料), j=5(指向最後一個數據), k=6(賦值為第一個資料的值)。

我們要把所有比k小的數移動到k的左面,所以我們可以開始尋找比6小的數,從j開始,從右往左找,不斷遞減變數j的值,我們找到第一個下標3的資料比6小,於是把資料3移到下標0的位置,把下標0的資料6移到下標3,完成第一次比較:

下標

0

1

2

3

4

5

資料

3

2

7

6

8

9

i=0 j=3 k=6

接著,開始第二次比較,這次要變成找比k大的了,而且要從前往後找了。遞加變數i,發現下標2的資料是第一個比k大的,於是用下標2的資料7和j指向的下標3的資料的6做交換,資料狀態變成下表:

下標

0

1

2

3

4

5

資料

3

2

6

7

8

9

i=2 j=3 k=6

稱上面兩次比較為一個迴圈。

接著,再遞減變數j,不斷重複進行上面的迴圈比較。

在本例中,我們進行一次迴圈,就發現i和j“碰頭”了:他們都指向了下標2。於是,第一遍比較結束。得到結果如下,凡是k(=6)左邊的數都比它小,凡是k右邊的數都比它大:

下標

0

1

2

3

4

5

資料

3

2

6

7

8

9

如果i和j沒有碰頭的話,就遞加i找大的,還沒有,就再遞減j找小的,如此反覆,不斷迴圈。注意判斷和尋找是同時進行的。

然後,對k兩邊的資料,再分組分別進行上述的過程,直到不能再分組為止。

注意:第一遍快速排序不會直接得到最終結果,只會把比k大和比k小的數分到k的兩邊。為了得到最後結果,需要再次對下標2兩邊的陣列分別執行此步驟,然後再分解陣列,直到陣列不能再分解為止(只有一個數據),才能得到正確結果。

程式碼如下:

import java.util.Arrays;
public class QuickSort {
    public static void main(String[] args){
        int[] arr = {6,3,2,9,1,8,7};
        quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    private static void quickSort(int[] arr,int low,int high) {
        int key = arr[low];
        int start = low;
        int end = high;
        while (start<end){
            while (end>start&&arr[end]>=key)
                end--;
            if (arr[end]<key){
                int temp = arr[end];
                arr[end]=arr[start];
                arr[start] = temp;
            }
            while (end>start&&arr[start]<=key)
                start++;
            if (arr[start]>key){
                int temp = arr[start];
                arr[start] = arr[end];
                arr[end] = temp;
            }
        }
        if(start>low) quickSort(arr,low,start-1);
        if(end<high) quickSort(arr,end+1,high);
    }
}