iT邦幫忙

2025 iThome 鐵人賽

DAY 6
0
佛心分享-IT 人自學之術

軟體工程師的湖濱散記系列 第 12

012 Insertion Sorting 雜談

  • 分享至 

  • xImage
  •  

Insertion Sorting 像是在玩 Poker,等到發牌的人發完牌的那刻,我們拿起手牌,通常都會把這堆無序的牌組重新排序,大多數人可能會從左至右、由小到大把牌整理好。

假設有五張牌,先不管花色,數字是 8, 4, 2, 13, 6,插入排序會把左一,也就是 8 當作起始點開始排序,跟下一張牌比大小,4 比 8 小,所以兩者要 "swap" 變成:

4, 8, 2, 13, 6

第二輪再往下一張牌去比,2 比 8 小,再次 swap 一次:

4, 2, 8, 13, 6

這時要把 current target 鎖定在 2 這個數字的位置,因為它要繼續跟前面的數字比看看,2 比 4 小所以要再 swap 一次:

2, 4, 8, 13, 6

然後才去 13 這邊,跟 8 比發現比它大就先不動,接著 6 比 13 小,所以 swap:

2, 4, 8, 6, 13

最後 6 再往前 swap 過來:

2, 4, 6, 8, 13

重點是在於 current target 要逐一跟前一個元素比對,不能像是我們實際玩牌那樣直接把牌插到正確位置,用程式碼實作的邏輯如下:

public static List<Integer> sortList(List<Integer> unsortedList) {
        for (int i = 0; i < unsortedList.size(); i++) {
            int current = i;
            while (current > 0 && unsortedList.get(current) < unsortedList.get(current - 1)) {
                int temp = unsortedList.get(current);
                unsortedList.set(current, unsortedList.get(current - 1));
                unsortedList.set(current - 1, temp);
                current--;
            }
        }
        return unsortedList;
    }

來看看這段邏輯具體的實作細節。

首先,能確定的是我們要迭代整個集合,要整理手牌當然是要把目光完整掃過每一張牌,不能漏掉某張,所以在這情況下從 0 開始用 for 迴圈迭代。

current 是為了每次排序到一個階段性的結果時,可以重新定位到要判斷的元素,因為不是每次互換後都可以直接往下做,我們還要考慮當前排序是否已經把最小的元素移動到最左邊了,如果還沒的話就要繼續比較,因此才有裡面的 while 迴圈,while 代表我們不確定要跑幾次,只要元素還能往前排就得繼續迭代。

current-- 是因為換完一輪後,小的那個元素已經往前移一格了,它要在那個位置繼續跟前一個元素比大小。

比完再回到大迴圈,大迴圈確保可以直接定位到下一個要判斷的地方。

最好的情況下時間複雜度是 O(n),代表已排序,while 不會執行。
最壞就是 O(n),巢狀迴圈。

空間都是 O(1),in-place 記憶體佔用小。

資料量小適合(50筆上下吧),或是原先排序就沒有很亂的話。


上一篇
011 Lua
下一篇
013 Selection Sorting 雜談
系列文
軟體工程師的湖濱散記13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言