快速排序——棧和數組——兩種思路(遞歸+挖坑填埋法)

原理:選取一個數,使得這個數的左邊比這個數小,右邊的數比這個數大。

接下來的問題是如果實現這個過程。


第一種用棧做


用棧做就太簡單了。

直接鎖定1。

從3開始往後找。

找到小的數,直接插入到1的前面。

再對每一部分進行遞歸。


這裏是找到了 0 0,新序列是 0 0 1 3 6 2 8 4 8

接下來就是 0 0裏找

再是3 6 2 8 4 8裏找。

。。。


這裏用List模擬的棧

// 136284008List實現太輕鬆了
void calculate(List<Integer> list, int startIndex, int endIndex) {// origin index 0 size-1
    if (startIndex == endIndex || startIndex + 1 == endIndex) {
        return;
    }

    int firstNum = list.get(startIndex);
    int index = startIndex;

    for (int i = startIndex + 1; i <= endIndex; i++) {
        int num = list.get(i);

        if (num < firstNum) {
            list.add(startIndex, num);
            list.remove(i + 1);
            index++;
        }
    }

    calculate(list, startIndex, index - 1);
    calculate(list, index + 1, endIndex);
}



第二種用數組做,略微麻煩一點。

沒有List那麼方便,需要挖坑。


我們依然選取1作爲參照數。

用X保存這個1。1就彷彿成了一個被挖出來的坑,因爲他的數已經被保存了,所以這個位置上可以任意賦值了。



之後從最後一位開始找比1小的數。8不符合。0是符合的。

所以這個0就填到剛剛第一位的坑裏,而0的那個位置有多出來一個坑。



接下來就是要從左邊開始找大的數,3直接就符合了。放到剛剛0的坑裏。而3又多出來一個坑。


接下來又是從右邊找。。。直到左右相遇。

//數組實現
void calculate(int a[], int startIndex, int endIndex) {
    if (startIndex == endIndex || startIndex + 1 == endIndex || startIndex > endIndex) {
        return;
    }

    int x = a[startIndex];
    int ken = startIndex;

    int s = startIndex;
    int e = endIndex;

    startIndex ++;

    boolean flag = true;

    while (startIndex <= endIndex) {
        if (flag) {
            if (x > a[endIndex]) {
                a[ken] = a[endIndex];
                ken = endIndex;
                flag = false;
            }
            endIndex --;//0
        } else {
            if (x < a[startIndex]) {
                a[ken] = a[startIndex];
                ken = startIndex;
                flag = true;
            }
            startIndex ++;
        }
    }

    a[ken] = x;

    calculate(a, s, ken - 1);
    calculate(a, ken + 1, e);
}