快排 java實現

快排 java實現

快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分爲較小和較大的2個子序列,而後遞歸地排序兩個子序列。java

快排的核心思想是:將要排序的序列(假設下標是從start到end)中選任意一個數據做爲pivot(分區點,也叫基準點),而後遍歷數據,將小於pivot 的數據放在pivot的前面,大於等於 pivot 的數據放在pivot的後面。以後遞歸的將兩個子序列排序。算法

過程以下。數組

快排1.PNG

這裏咱們給出的是原地排序的實現,也就是算法的執行過程當中不須要額外的空間。ide

public class Quick {
    // 快速排序,a是數組,n表示數組的大小
    public static void quickSort(int[] a, int n) {
        quickSortInternally(a, 0, n - 1);
    }

    // 快速排序遞歸函數
    private static void quickSortInternally(int[] a, int start, int end) {
        if (start >= end) {
            return;
        }

        int q = partition(a, start, end); // 獲取分區點
        quickSortInternally(a, start, q - 1);
        quickSortInternally(a, q + 1, end);
    }
}

上面的這個是遞歸實現的,能夠看出跟歸併排序的代碼有點類似,這裏最主要的就是分區點的獲取。函數

private static int partition(int[] a, int start, int end) {
    int pivot = a[end];
    int i = start;
    for (int j = start; j < end; ++j) {
        if (a[j] < pivot) {
            if (i == j) {
                ++i;
            } else {
                swap(a, i, j);
                ++i;
            }
        }
    }
    swap(a, i, end);
    return i;
}

public static void swap(int[] a, int i, int j) {
    int tmp = a[i];
    a[i] = a[j];
    a[j] = tmp;
}

在這裏咱們的分區點都是選擇須要排列的數組的最後一個節點。下面有第一個分區點的獲取步驟的演示,能夠看看。ui

快排.gif

能夠看出 i 始終指向的是數組中第一個值大於分區點的節點,j 則是遍歷數組,尋找值小於分區點的節點,而後與i指向的節點交換位置,以後i++,這樣當j遍歷一遍數組後i左邊的都是值小於分區點的,i右邊都是值大於等於分區點,最後i與分區點交換位置。這樣第一遍遍歷就完成了。code

快排是一種原地、不穩定的算法,他的時間複雜度是 O(nlogn),相比較於歸併排序,快排具備空間的優點,可是他的時間複雜度並不如歸併排序那麼穩定,當須要排列的數組近乎有序時,咱們仍選擇最後一個元素做爲分區點的話,快排的時間複雜度就變成了O(n2)了,blog

相關文章
相關標籤/搜索