快速排序的基本實現(Java)
快速排序的關鍵步驟是將基準數歸位。
舉個例子,假定有一個數組:int[] arr = {4,5,1,2,6,8,9,3,7}
,並且我們要把他按從小到大排序。
選定第一個元素4作爲基準數,歸位的意思是要把它放到應該放的位置上去,同時左邊的數都小於基準數,右邊的數都大於基準數。
可以設兩個變量,我給他們取名爲leftWalker和rightWalker。首先rightWalker從右到左找一個比基準數小的數,然後leftWalker從左到右找一個比基準數大的數,將他們所指的值交換;當兩個walker撞到一起時,就把基準數和兩個walker所指的數進行交換,此時基準數歸位完畢。
我們可以將基準數歸位的操作封裝爲一個函數restoreFIrst(int[] array)。當前數組進行一次基準數歸位後,後面要做的就是對基準數左邊的元素組成的數組和基準數右邊的元素組成的數組分別進行基準數歸位,這裏應用了遞歸解決問題的思想,例如:
arr1 arr2 arr3 arr4 arr5 **index** arr6 arr7 arr8 arr9
下面要做的是restoreFirst({arr1,arr2,arr3,arr4,arr5})
和restoreFirst({arr6,arr7,arr8,arr9})
很重要的問題,遞歸的出口是當前array的長度小於1時,直接return。
當所有子序列處理完畢後,快速排序也就結束了,這時可以輸出排序後的結果。
附完整代碼:
package com.adam.sort;
import java.util.Arrays;
/**
* @author adam
* 創建於 2018-03-05 22:27.
* 快速排序(從小到大)。
*/
public class QuickSort {
public static void main(String[] args) {
int[] array = {6,8,4,3,5,2,9,1,7,19,-2};
quicksort(array,0,array.length-1);
System.out.println(Arrays.toString(array));
}
private static void quicksort(int[] array,int startIndex, int endIndex) {
int index = restoreFirst(array,startIndex,endIndex);
if(index==-1){
return;
} else {
quicksort(array,startIndex,index);
quicksort(array,index+1,endIndex);
}
}
//返回值:歸位後基準數index
private static int restoreFirst(int[] array,int startIndex,int endIndex) {
if(endIndex-startIndex <= 0){
return -1;
} else {
int first = array[startIndex]; //基準數
int leftWalker = startIndex, rightWalker = endIndex; //左右哨兵
while(true) {
//從右面找一個比first小的數
while(array[rightWalker] >= first && rightWalker > leftWalker)
rightWalker--;
//從左面找一個比first大的數
while(array[leftWalker] <= first && leftWalker < rightWalker)
leftWalker++;
//當左右哨兵不等時,交換這兩個哨兵指向的值
if(leftWalker != rightWalker) {
int temp = array[leftWalker];
array[leftWalker] = array[rightWalker];
array[rightWalker] = temp;
} else { //否則將哨兵所指的值與基準數交換
array[startIndex] = array[leftWalker];
array[leftWalker] = first;
return leftWalker;
}
}
//跳出循環時,基準數已歸位
}
}
}
運行結果:
[-2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 19]
2019/06/01
附第二種實現方式:
public class QuickSortMain {
public static void main(String[] args) {
int[] arr = {90,45,200,1,48,8899,23};
sort(arr, 0, arr.length-1);
System.out.println(Arrays.toString(arr));
}
private static void sort(int[] arr, int left, int right) {
if(left >= right) return;
int base = arr[left];
int lw = left, rw=right;
while(lw!=rw) {
//注意:此處必須先從右邊找。因爲基準數選的是左邊第一個。
while (lw < rw && arr[rw] >= base) rw--;
while (lw < rw && arr[lw] <= base) lw++;
if (lw != rw) {
int tmp = arr[lw];
arr[lw] = arr[rw];
arr[rw] = tmp;
}
}
if(lw!=left) {
arr[left] = arr[lw];
arr[lw] = base;
}
sort(arr, left, lw-1);
sort(arr, lw+1, right);
}
}