插入排序法

更新於 發佈於 閱讀時間約 3 分鐘

前導

插入排序(Insertion Sort),它的概念類似於撲克牌整理,我們拿起一張牌並將它插入到已排序的牌堆中,使整堆牌仍然保持有序。

演算法流程

假設陣列長度為n,我們要做的就只是將陣列中的元素,逐一與已排序好的資料做比較。

實際範例

假設一原始陣列如下:

[12, 11, 13, 5, 6]

排序步驟

  1. 第一次迭代(i = 1):
    • 當前要插入的元素(未排序區域的第一個元素):11
    • 已排序區域:[12]
    • 比較:11 與 12 比較,因 11 < 12
    • 將 12 向右移動,並在最前面插入 11
    • 結果:[11, 12, 13, 5, 6]
  2. 第二次迭代(i = 2):
    • 當前要插入的元素(未排序區域的第一個元素):13
    • 已排序區域:[11, 12]
    • 比較:13 與 12 比較,因 13 ≥ 12,不需要移動
    • 結果保持不變:[11, 12, 13, 5, 6]
  3. 第三次迭代(i = 3):
    • 當前要插入的元素(未排序區域的第一個元素):5
    • 已排序區域:[11, 12, 13]
    • 比較過程: 5 < 13 → 繼續比較 5 < 12 → 繼續比較 5 < 11 → 繼續比較...
    • 將 5 插入最前面,因為離開迴圈,arr[-1 + 1] = key;
    • 結果:[5, 11, 12, 13, 6]
  4. 第四次迭代(i = 4):
    • 當前要插入的元素(未排序區域的第一個元素):6
    • 已排序區域:[5, 11, 12, 13]
    • 比較過程: 6 < 13 → 繼續比較 6 < 12 → 繼續比較 6 < 11 → 繼續比較 6 ≥ 5 → 找到插入位置
    • 將 6 插入在 5 與 11 之間
    • 結果:[5, 6, 11, 12, 13]

最終排序結果:

[5, 6, 11, 12, 13]

程式碼

#include <stdio.h>

// 插入排序函式
void insertionSort(int arr[], int n) {
for (int i = 1; i < n; i++) {
int key = arr[i]; // 當前要插入的數
int j = i - 1;

// 向右移動比 key 大的元素,為 key 騰出位置
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--; //繼續比較,向左遍歷已排序部分的陣列,找到合適的位置來插入 key。
}

arr[j + 1] = key; // 插入 key
}
}

// 輔助函式:列印陣列
void printArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}

// 主程式
int main() {
int arr[] = {12, 11, 13, 5, 6};
int n = sizeof(arr) / sizeof(arr[0]);

printf("排序前: ");
printArray(arr, n);

insertionSort(arr, n);

printf("排序後: ");
printArray(arr, n);
return 0;
}
在當今數位時代,電資領域人才需求爆發式成長,不論是前端網頁設計、嵌入式開發、人工智慧、物聯網還是軟硬體整合,這些技術都在改變世界。而掌握 C/C++、Python、數位邏輯、電路學與嵌入式開發等大學電資領域的課程,正是進入這個高薪、高需求產業的關鍵!
留言
avatar-img
留言分享你的想法!
本章節我們將探討選擇排序法的運作流程,最後用程式碼實作。
氣泡排序(Bubble Sort)是一種簡單但效能較低的排序演算法。它的核心概念是「兩兩比較、交換」。 本章節會以最淺顯易懂的描述搭配圖示,讓讀者了解該演算法的觀念。
相信你對於演算法有了一點認識,如果今天要求您將一組牌進行洗牌的動作,該怎麼做? 本章節將提供兩個實際操作,讓讀者能夠對洗牌的演算法思維有深刻的了解,並為之後的章節暖暖身。
寫同樣的一段程式碼,別人的code卻比自己寫的code還要有效率,也就是跑得更快,為什麼呢? 其根本原因很可能出在演算法的問題上。 本章節以 找出所有質數(Prime Numbers) 為例,展示不同的演算法在效率上展現的巨大差異。並帶領讀者了解演算法的本質。
本章節我們將探討選擇排序法的運作流程,最後用程式碼實作。
氣泡排序(Bubble Sort)是一種簡單但效能較低的排序演算法。它的核心概念是「兩兩比較、交換」。 本章節會以最淺顯易懂的描述搭配圖示,讓讀者了解該演算法的觀念。
相信你對於演算法有了一點認識,如果今天要求您將一組牌進行洗牌的動作,該怎麼做? 本章節將提供兩個實際操作,讓讀者能夠對洗牌的演算法思維有深刻的了解,並為之後的章節暖暖身。
寫同樣的一段程式碼,別人的code卻比自己寫的code還要有效率,也就是跑得更快,為什麼呢? 其根本原因很可能出在演算法的問題上。 本章節以 找出所有質數(Prime Numbers) 為例,展示不同的演算法在效率上展現的巨大差異。並帶領讀者了解演算法的本質。
你可能也想看
Google News 追蹤
Thumbnail
靈感用盡、鍵盤不再響,盯著喜歡、分享、留言的數字,心跳跟著小鈴鐺七上八下⋯⋯vocus 2025 年 4 月限定新商品,要為創作者打氣! 🚨「創作者打氣包」 最懂創作者的vocus,為創作者打造 ✨ 打氣包,包什麼?!四件道具挺創作者 一、【打氣復活卷】 專屬你的打氣小語,成功登記免費
Thumbnail
全新 vocus 挑戰活動「方格人氣王」來啦~四大挑戰任你選,留言 / 愛心 / 瀏覽數大 PK,還有新手專屬挑戰!無論你是 vocus 上活躍創作者或剛加入的新手,都有機會被更多人看見,獲得站上版位曝光&豐富獎勵!🏆
Thumbnail
題目敘述 Sort Array by Increasing Frequency Leetcode #1636 給定一個輸入陣列,請依照出現頻率的多寡從低頻到高頻排列陣列元素。 如果有兩個元素的出現頻率相同,依照元素大小從大到小排列。 測試範例 Example 1: Input: nums
Thumbnail
給定兩個輸入陣列,第一個陣列代表每個人的姓名,第二個陣列代表每個人的身高。依照身高從高到矮進行排列,輸出每個人的名字。本文介紹了一個根據身高排列人名的算法,並提供了相關的程式碼和時間複雜度分析。
Thumbnail
給定一個整數陣列hand代表手牌點數,和參數groupSize。請問能不能每groupSize牌一組,每一組都拼出順子? 如果可以,返回True。如果無解,返回False。演算法使用最小堆積或排序。關鍵知識點:從小到大掃描每張牌,檢查能不能組成牌組長度為groupSize的順子即可。
Thumbnail
本文章討論如何使用動態規劃和回頭查看技巧來計算最長遞增子序列的長度,並提供了相關的測試案例和範例。本文還包括了詳細的演算法和程式碼示例,以及時間和空間複雜度的分析。
Thumbnail
給定一個輸入非負整樹陣列nums,請找出k值,使得陣列中恰好有k個元素大於等於 k。如果無解,回傳-1。尋找k值的方法包括排序法和二分搜尋法,時間複雜度都為O(n log n),空間複雜度為O(1)。關鍵知識點是當解空間具有遞增或遞減的性質時,可以用二分搜尋法加快搜尋效率。
Thumbnail
題目已經給了依照起點升序排列好的區間陣列。 接下來新插入一個區間,插入後如果和原本的區間重疊,請把他們合併,要求我們輸出插入後的結果。 這是一個線性掃苗,所需時間為O(n)的演算法。 題目已經幫我們排序好區間順序,我們只要接著依序檢查區間、(假如有重疊的話)合併區間。
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目敘述 題目會給定我們兩個字串。 第一個是指定順序的字串order。 第二個是輸入字串s。 要求我們依據order給定的順序,重新排列s。 如果出現order中沒有出現的字母,任意位置皆可。 合法答案可能不只一組,輸出其中一種即可。 題目的原文敘述 測試範例 Example
Thumbnail
最近每天都有同學在解題社群提問這類型的問題,有些同學甚至po出解答來提問,表示看了解答卻還是看不懂,畢竟有時候「詳解」也沒辦法完整表達所有觀念。 排列組合是一門龐大的章節,許多人聞排組而色變,但排列組合的本質其實還是「窮舉法」,也就是把全部的可能通通列出來,只是很多地方我們可以透過計算讓窮舉變得更
Thumbnail
題目敘述 題目給定我們一個輸入陣列nums 要求我們以正、負交叉排列的方式重組陣列,並且必須保持原本的相對順序。 並且以陣列的形式輸出返回答案。 例[5, 1, -2, -3] 重排後為 [5, -2, 1, -3] 題目的原文敘述 測試範例 Example 1: Input:
Thumbnail
靈感用盡、鍵盤不再響,盯著喜歡、分享、留言的數字,心跳跟著小鈴鐺七上八下⋯⋯vocus 2025 年 4 月限定新商品,要為創作者打氣! 🚨「創作者打氣包」 最懂創作者的vocus,為創作者打造 ✨ 打氣包,包什麼?!四件道具挺創作者 一、【打氣復活卷】 專屬你的打氣小語,成功登記免費
Thumbnail
全新 vocus 挑戰活動「方格人氣王」來啦~四大挑戰任你選,留言 / 愛心 / 瀏覽數大 PK,還有新手專屬挑戰!無論你是 vocus 上活躍創作者或剛加入的新手,都有機會被更多人看見,獲得站上版位曝光&豐富獎勵!🏆
Thumbnail
題目敘述 Sort Array by Increasing Frequency Leetcode #1636 給定一個輸入陣列,請依照出現頻率的多寡從低頻到高頻排列陣列元素。 如果有兩個元素的出現頻率相同,依照元素大小從大到小排列。 測試範例 Example 1: Input: nums
Thumbnail
給定兩個輸入陣列,第一個陣列代表每個人的姓名,第二個陣列代表每個人的身高。依照身高從高到矮進行排列,輸出每個人的名字。本文介紹了一個根據身高排列人名的算法,並提供了相關的程式碼和時間複雜度分析。
Thumbnail
給定一個整數陣列hand代表手牌點數,和參數groupSize。請問能不能每groupSize牌一組,每一組都拼出順子? 如果可以,返回True。如果無解,返回False。演算法使用最小堆積或排序。關鍵知識點:從小到大掃描每張牌,檢查能不能組成牌組長度為groupSize的順子即可。
Thumbnail
本文章討論如何使用動態規劃和回頭查看技巧來計算最長遞增子序列的長度,並提供了相關的測試案例和範例。本文還包括了詳細的演算法和程式碼示例,以及時間和空間複雜度的分析。
Thumbnail
給定一個輸入非負整樹陣列nums,請找出k值,使得陣列中恰好有k個元素大於等於 k。如果無解,回傳-1。尋找k值的方法包括排序法和二分搜尋法,時間複雜度都為O(n log n),空間複雜度為O(1)。關鍵知識點是當解空間具有遞增或遞減的性質時,可以用二分搜尋法加快搜尋效率。
Thumbnail
題目已經給了依照起點升序排列好的區間陣列。 接下來新插入一個區間,插入後如果和原本的區間重疊,請把他們合併,要求我們輸出插入後的結果。 這是一個線性掃苗,所需時間為O(n)的演算法。 題目已經幫我們排序好區間順序,我們只要接著依序檢查區間、(假如有重疊的話)合併區間。
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目敘述 題目會給定我們兩個字串。 第一個是指定順序的字串order。 第二個是輸入字串s。 要求我們依據order給定的順序,重新排列s。 如果出現order中沒有出現的字母,任意位置皆可。 合法答案可能不只一組,輸出其中一種即可。 題目的原文敘述 測試範例 Example
Thumbnail
最近每天都有同學在解題社群提問這類型的問題,有些同學甚至po出解答來提問,表示看了解答卻還是看不懂,畢竟有時候「詳解」也沒辦法完整表達所有觀念。 排列組合是一門龐大的章節,許多人聞排組而色變,但排列組合的本質其實還是「窮舉法」,也就是把全部的可能通通列出來,只是很多地方我們可以透過計算讓窮舉變得更
Thumbnail
題目敘述 題目給定我們一個輸入陣列nums 要求我們以正、負交叉排列的方式重組陣列,並且必須保持原本的相對順序。 並且以陣列的形式輸出返回答案。 例[5, 1, -2, -3] 重排後為 [5, -2, 1, -3] 題目的原文敘述 測試範例 Example 1: Input: