Java 遞迴與非遞迴實現快速排序
阿新 • • 發佈:2019-02-09
快速排序演算法
工作之前一直不懂快速排序演算法,今天看了下快速排序演算法,跟大家分享下,如果有不妥之處還請建議。
快速排序是對氣泡排序的一種改進,由C.R.A.Hoare於1962年提出,它採用了一種分治的策略,通常稱其為分治法(Divide-and-ConquerMethod)。
基本思想:
1.先從數列中取出一個數作為控制字。如陣列 [K 1 ,K 2 ,…,K n ],以第一個關鍵字 K 1 為控制字。
2.分割槽過程,將比這個控制字大的數全放到它的右邊,小於或等於它的數全放到它的左邊。如將 [K 1 ,K 2 ,…,K n ] 分成兩個子區,使左區所有關鍵字小於等於 K 1 ,右區所有關鍵字大於等於 K 1 。
3.再對左右區間重複第二步,直到各區間只有一個數
Java 程式碼如下,直接呼叫 quickSort(int[] array)函式, 將要排序的陣列傳入函式中, 在函式中會打印出排序後的結果。
public static void quickSort(int[] array) {
qsort(array, 0, array.length -1);
for (int i= 0; i < array.length; i++ ) {
System.out.println(" the result :" + array[i]);
}
}
//遞迴方法
public static void qsort(int[] array, int left, int right) {
if (left < right) {
int partition = partition(array, left, right);
qsort(array, 0, partition - 1);
qsort(array, partition +1, right);
}
}
//非遞迴實現
private static void quickSort (int[] array) {
if (array == null || array.length == 1) {
return;
}
//存放開始於結束索引
Stack<Integer> stack = new Stack<>();
stack.push(0);
stack.push(array.length - 1);
//迴圈讀取棧中的開始結束位置
while (!stack.isEmpty()) {
int right = stack.pop();
int left = stack.pop();
//右邊界索引小於左邊界索引說明結束了
if (left >= right) {
continue;
}
int i = partition(array, left, right);
if (left < i - 1) {
stack.push(left);
stack.push(i - 1);
}
if (i + 1 < right) {
stack.push(i + 1);
stack.push(right);
}
}
}
public static int partition(int[] array, int left, int right) {
int threshold = array[left];
while (left < right) {
while (left < right && array[right] >= threshold) {
right--;
}
array[left] = array[right];
while (left < right && array[left] <= threshold) {
left++;
}
array[right] = array[left];
}
array[left] = threshold;
return left;
}
遞迴演算法使用的棧由程式自動產生,棧中包含:函式呼叫時的引數和函式中的區域性變數。如果區域性變數很多或者函式內部又呼叫了其他函式,則棧會很大。每次遞迴呼叫都要操作很大的棧,效率自然會下降。