【TODO】【算法】快速排序

0. 索引

1. 簡單介紹

關於原理,雖然很重要,可是在這裏不作過多介紹。 由於隨便搜索一下。就能夠找到更好的答案。java

本質是回顧,記住核心的思想,而後經過code 深入 已有概念的印象。數組

2. 雙邊循環法

/**
 * 快速排序的基本方法
 *
 * @param intArr     待排序的數組
 * @param startIndex 開始的 index
 * @param endIndex   結束的 index
 * @return 循環次數
 */
public static long sort(int[] intArr, int startIndex, int endIndex) {
    if (startIndex >= endIndex) {
        return 0;
    }
    // 找到基準位置。 位置左邊的的都是小於的,位置右邊的都是大於的。 + 同事作好了排序
    int pivotIndex = doubleSideSortFindPivot(intArr, startIndex, endIndex);

    sort(intArr, startIndex, pivotIndex - 1);
    sort(intArr, pivotIndex + 1, endIndex);

    return 1;
}

/**
 * 分治(雙邊循環法)
 *
 * @param intArr     待交換的數組
 * @param startIndex 起始下標
 * @param endIndex   結束下標
 */
public static int doubleSideSortFindPivot(int[] intArr, int startIndex, int endIndex) {
    int pivotVal   = intArr[startIndex];
    int leftIndex  = startIndex;
    int rightIndex = endIndex;

    // MARK : 以前用if leftIndex < rightIndex 報錯
    while (leftIndex != rightIndex) {

        // 以前本身的寫法比較混亂
        // step 1 :控制 right 指針,左移
        // 錯誤1 : 使用了 if ,畢竟能夠一直左移。 邏輯判斷 MARK
        while (leftIndex < rightIndex && intArr[rightIndex] > pivotVal) {
            rightIndex--;
        }
        // step 2 : 控制 left 指針 右移
        while (leftIndex < rightIndex && intArr[leftIndex] <= pivotVal) {
            leftIndex++;
        }

        // step 3 :交換 left 和 right。 須要加限制條件
        if (leftIndex < rightIndex) {
            int temp = intArr[leftIndex];
            intArr[leftIndex] = intArr[rightIndex];
            intArr[rightIndex] = temp;
        }
    }

    // 【replace】pivot和指針重合點交換
    intArr[startIndex] = intArr[leftIndex];
    intArr[leftIndex] = pivotVal;

    return leftIndex;
}

3. 單邊循環法

/**
 * 分治(單循環法) 把 小於基準值的,交換(和基準值的index )到 pivot 的左邊
 *
 * @param intArr     待交換的數組
 * @param startIndex 起始下標
 * @param endIndex   結束下標
 */
public static int oneSideSort(int[] intArr, int startIndex, int endIndex) {
    // 默認起始位置爲基準值
    int pivotVal = intArr[startIndex];
    // 基準值的位置,不斷移動。左邊的表明交換過來的小於 pivotVal 的
    int mark = startIndex;

    // 若是小於基準值的,交換,mark 右移
    for (int i = startIndex + 1; i <= endIndex; i++) {
        // 小於的作交換
        if (intArr[i] < pivotVal) {
            mark++; // 基準位右移
            int temp = intArr[mark];
            intArr[mark] = intArr[i];
            intArr[i] = temp;
        }
    }

    // 交換
    intArr[startIndex] = intArr[mark];
    intArr[mark] = pivotVal;

    return mark;
}
相關文章
相關標籤/搜索