經過圖文的方式解釋排序算法

插入排序java

插入排序是最簡單的一種排序方式。這裏就不去囉嗦繞口的概念了,經過圖去解釋什麼是插入排序程序員

假設一個數組內有以下5個元素,須要對其按照從小到大的順序進行排列。面試

插入排序就是從未排序序列中,取出元素,在已排序序列中一次比較。插入到相應的位置。算法

在上面的五個數字中數組

  1. 咱們假設有一個長度爲一的有序系列爲12。學習

  2. 而八、1七、3一、22爲無序序列。大數據

  3. 從無序序列中取出一個元素8,與有序序列中的12進行比較。比12小,則將其移動到12前面,反之放在後面spa

結果爲:3d

 

public static void main(String[] args) {
        Integer[] arr = {12, 8, 17, 31, 22};
        // 第一個元素爲有序,所以從i = 1開始
        for (int i = 1; i < arr.length; i++) {
            // 待插入元素 第一次循環arr[i] 就是8
            Integer temp = arr[i];
            int j;
            for (j = i - 1; j >= 0; j--) {
                // 數組中第二個元素與第一個元素比較,12>8
                if (temp < arr[j])
                /**
                 * 複製j位元素到j+1
                 * 循環一次是,結果爲十二、十二、1七、3一、22
                 */
                    arr[j + 1] = arr[j];
                else
                    break;
            }
            /**
             * j + 1 位爲要插入的最小元素
             * 循環一次結果爲八、十二、1七、3一、22
             */
            arr[j + 1] = temp;
        }
        System.out.println(Arrays.toString(arr));
    }

  

 

二分排序code

 

在說二分排序以前不得不提到二分查找這個基本的算法。那什麼是二分查找呢?

 

舉個例子,你們應該都玩過猜數字的遊戲,若是從1~100這裏面猜一個數字。我只須要對你猜的數字回答 「大了」、「小了」。直至猜出結果。

 

若是漫無目的的去猜,運氣很差可能會猜100次。那怎麼樣才能更少次數的猜出結果呢。

 

假設咱們的目標數字是 66

 

 

對於N個元素的列表,咱們要猜出其中一個數字最多隻須要log 2 N次。若是列表中1024個數字,咱們也只須要猜想10次就能夠出來。2的十次方等於1024.

 

回到咱們的二分插入,原理基本同樣,從無序列表中取出一個元素,跟前面的有序列表的中間數進行比較,若是小了,再進行折半比較,直至找到合適的位置。

 

如圖,六、九、十二、1八、20爲有序列表,對15進行二分插入

 

 

  • 取出有序列表的中間元素12。12< 15。

  • 十二、1八、20取出中間元素,18。18 > 15

  • 在十二、18中進行比較,12<15<18

public static void main(String[] args) {
        int i, j, right, left, mid, temp;
        Integer[] arr = {12, 8, 17, 31, 22, 44, 1, 99, 76};
        // 依舊把第一個元素當成有序的,所以從i=1開始
        for (i = 1; i < arr.length; i++) {
            //若是後一個元素比前一個元素大,則continue,開始下一次循環
            if (arr[i] > arr[i - 1]) {
                continue;
            }
            temp = arr[i];
            //最左邊爲二分插入的起始位置
            left = 0;
            //左右定義有序列表的長度
            right = i-1;
            while (left <= right) {
                //mid爲中間元素的下標
                mid = (left + right) / 2;
                // 中間元素和要插入的元素進行比較
                if (arr[mid] < temp)
                    //若是中間元素小,則起始位置爲mid + 1
                    left = mid + 1;
                else
                    //同left
                    right = mid - 1;
            }
            // 移動元素到相應的位置
            for (j = i - 1; j >= left; j--) {
                arr[j + 1] = arr[j];
            }
            arr[left] = temp;
        }
        System.out.println(Arrays.toString(arr));
    }

  

希爾排序

 

希爾排序又成爲縮小增量排序。假設有一個長度爲N的數組,他的增量設爲X(X<N),將數組拆分爲多個子序列,在每一個子序列中進行直接插入排序。而後減小增量的值,重複以上操做,直至X=1(即一個子序列中只有一個元素)。這樣理解可能比較混亂,看圖說話吧。

 

如圖,一個長度爲8的無序數組

 

 

增量一般取長度的通常,因此增量爲 8/2 = 4。意味着此時被拆分爲4個子序列。

[18 , 10], [22,1],[3,19],[51,55]

我用四種不一樣的顏色進行標識

而後子序列中的元素進行插入排序,即同一顏色的兩個數進行排序,結果爲

而後縮小增量,此時增量爲4/2 = 2。被分爲兩個子序列

[10,3,18,19] ,[1,5 1,22,55]

 

 再次對子序列進行排序,獲得的結果以下

 

重複上述操做,再次縮小增量直至爲1,通過增量遞減的過程,其實就是元素排序的過程,當增量爲1時,大部分元素其實已經排好順序了,咱們只須要對其進行微調便可。

 

代碼實現以下

public static void main(String[] args) {
        Integer[] arr = {18, 22, 3, 51, 10, 1, 19, 55};
        // 初始增量一般爲總長度的一半
        int mid = arr.length / 2;
        int i;
        while (mid > 0) {
            for (i = mid; i < arr.length; i++) {
                // 起始下標
                int begin = i - mid;
                int tmp = arr[i];
                // 起始下標元素大 則調整位置,
                while (begin >= 0 && arr[begin] > arr[i]) {
                    arr[begin + mid] = arr[begin];
                    begin -= mid;
                }
                //而且調換位置
                arr[begin + mid] = tmp;
            }
            // 每次結束,增量縮小一半。也能夠自定義
            mid = mid / 2;
            System.out.println(Arrays.toString(arr));
        }
    }

 

總結

 

插入排序適用於少許數據的排序,其時間複雜度爲O(n^2)。

 

二分排序則是利用了數組可以快速定位的特色,時間複雜度也是O(n^2),適用於較大數據排序

 

希爾排序的實質是分組再進行直接插入,開始時增量較大時,插入排序的數量少,因此前期會很快。當增量變小時,數據也基本有序了。因此希爾排序的時間複雜度要比O(n^2)要好不少。

 

 

 最後 歡迎你們關注個人公衆號 程序員共成長。天天都會分享技術乾貨,包括不限於Java、數據量、Linux、職場感悟,大廠面試等。另外還有各類學習資源

相關文章
相關標籤/搜索