1. 程式人生 > >Java 遞迴與非遞迴實現快速排序

Java 遞迴與非遞迴實現快速排序

快速排序演算法

工作之前一直不懂快速排序演算法,今天看了下快速排序演算法,跟大家分享下,如果有不妥之處還請建議。

快速排序是對氣泡排序的一種改進,由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; }

遞迴演算法使用的棧由程式自動產生,棧中包含:函式呼叫時的引數和函式中的區域性變數。如果區域性變數很多或者函式內部又呼叫了其他函式,則棧會很大。每次遞迴呼叫都要操作很大的棧,效率自然會下降。