經典排序演算法之--快速排序
快速排序是一種高效但不穩的排序演算法,不穩性取決於比較基數的選擇帶有隨機性,其排序原理應用百度百科如下:
設要排序的陣列是A[0]……A[N-1],首先任意選取一個數據(通常選用陣列的第一個數)作為關鍵資料,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序。值得注意的是,快速排序不是一種穩定的排序演算法,也就是說,多個相同的值的相對位置也許會在演算法結束時產生變動。
一趟快速排序的演算法是:
1)設定兩個變數i、j,排序開始的時候:i=0,j=N-1;
2)以第一個陣列元素作為關鍵資料,賦值給key,即key=A[0];
3)從j開始向前搜尋,即由後開始向前搜尋(j--),找到第一個小於key
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);
}
}