挖坑填數+分治法:快速排序

Gooder4J發表於2020-10-18
版本更新說明時間
1.0新增本部落格2020/10/18

1. 理論基礎

挖坑填數+分治法可以很形象的講述快速排序:
假設有如下陣列array

0123456789
7265788604283734885

現在我們要對它做升序排序

第一步,取基準數
理論上陣列的任一元素都可以作為基準數,這裡我們選擇第0號元素72,base = array[left]
現在陣列可以看成:

0123456789
65788604283734885

left

right

實際上0號位72仍然存在,但我們通過base將0號位的72儲存下來的,此時0號位上的元素可以被覆蓋,因此邏輯上我們抽象地將0號位看成空白,下面的論述仍然是如此

第二步:填坑
第一個坑已經出來,接下來我們就需要填這個坑:從右到左(←)找一個小於base的數

我們找到了

0123456789
65788604283734885

left

right

填進去

0123456789
48657886042837385

left

right

接下來從左向右(→)找到比base大的數,填充進去

0123456789
48657886042837385

left

right
0123456789
48657604283738885

left

right

依次類推,一個輪迴之後,就會變成如下陣列

0123456789
4865742607283738885

base=72為基準,左邊的數都小於大,右邊的數都大於它,
接下來再對左右兩邊進行如此的快排,就能得到一個有序的陣列

2. 程式碼實現


    public static void quickSort(int[] array, int left, int right){
        if(left < right) {
            int l = left, r = right;
            int base = array[l];
            while (l < r) {
                // l小於r, 並且當前元素大於base,則繼續向前尋找
                while (l < r && array[r] >= base) {
                    r--;
                }

                if (l < r) {
                    array[l] = array[r];
                    l++;
                }
                
                // l小於r, 並且當前元素小於base,則繼續向前尋找
                while (l < r && array[l] <= base) {
                    l++;
                }

                if (l < r) {
                    array[r] = array[l];
                    r--;
                }

            }

            array[l] = base;

            quickSort(array, left, l - 1);
            quickSort(array, r + 1, right);
        }
    }

3. 時間複雜度

最優情況: O ( l o g 2 n ) O(log_2n) O(log2n),每次都平分
最差情況: O ( n 2 ) O(n^2) O(n2),每次都取到最大或最小,也就變成了氣泡排序
平均情況: O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)

相關文章