在 C 語言中使用鏈結串列的優勢

更新 發佈閱讀 8 分鐘


在 C 語言中,陣列的大小是固定的,並且使用連續的記憶體空間。如果要在陣列中間插入新元素,可能會變得麻煩。例如,當我要在 1, 2, 3 後插入 4 時,若後面的記憶體區塊已被佔用,就無法直接插入。此時,必須找到足夠大的空間來重新複製資料。這樣的過程不僅耗時,也不靈活。

這時,鏈結串列就派上用場了!

插入4,要先找到其他的儲存格。圖片來源:CS50。

插入4,要先找到其他的儲存格。圖片來源:CS50。

鏈結串列是什麼?

鏈結串列是一種更靈活的資料結構,它不需要連續的記憶體空間,。鏈結串列由一連串的節點組成,每個節點包含資料和一個指向下一個節點的指標。當需要插入新元素時,只需更新指標來連接新節點,這樣就避免了重新分配大區塊記憶體的麻煩。

程式碼的顯示

指到下一個節點

之前的文章提過,C 語言可以自己建立資料型態:

演算法 | Big O 複雜度| Pseudocode 偽代碼

typedef struct
{
string name;
string number;
}person;

而鏈結串列會有一個 node 節點,而他會指向下個地址

#include <stdio.h>

typedef struct node
{
int number;
struct node *next; //指向下個 node
} node;
node *life; //建立一個指標變數life,他指向的資料型別是node

但是隨便指向沒有資料的地方,會出現電腦隨便丟垃圾訊息。所以我們要分配記憶體給他,

node *n = malloc(sizeof(node));// n是個指標變數,指向的值的資料型別是node
(*n).number = 1: // *指向下個node,"."的意思是在資料型別為number的地方

(*n).number = 1 可以簡化成 n->number =1

圖像化鏈結串列

命令列參數中的數字插入一個鏈結串列 (linked list) ,插到最前面

圖片來源:CS50

raw-image

接下來,如何把 n 連起來換給 list,把 n 賦值給 list。

raw-image


raw-image

接下來如何把1和2串在一起?不是直接 list = n !

raw-image
raw-image
raw-image


數字插入一個鏈結串列 (linked list) 中

新的節點 (數字) 插入到兩個已有節點之間的程式碼如下,往下還有圖片說明:

#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>

// 定義一個節點的結構,包含數字和指向下一個節點的指標
typedef struct node
{
int number; // 節點中的數字
struct node *next; // 指向下一個節點的指標
}
node;

int main(int argc, char *argv[])
{
// 初始化鏈結串列為空
node *list = NULL;

// 逐一處理每個命令列參數
for (int i = 1; i < argc; i++)
{
// 將參數轉換成整數
int number = atoi(argv[i]);

// 為該數字分配一個新的節點
node *n = malloc(sizeof(node));
if (n == NULL) // 檢查是否成功分配記憶體
{
return 1; // 若失敗,返回錯誤代碼 1
}
n->number = number; // 將數字儲存在節點中
n->next = NULL; // 新節點的下一個指標先設為空

// 如果鏈結串列為空,將這個節點作為鏈結串列的第一個節點
if (list == NULL)
{
list = n;
}

// 如果該數字應該放在鏈結串列的開頭
else if (n->number < list->number)
{
n->next = list; // 將新節點的指標指向原本的第一個節點
list = n; // 新節點成為鏈結串列的第一個節點
}

// 如果該數字應該放在串列的中間或末端
else
{
// 遍歷鏈結串列,尋找適當的位置插入
for (node *ptr = list; ptr != NULL; ptr = ptr->next)
{
// 如果已經到了鏈結串列的末端
if (ptr->next == NULL)
{
ptr->next = n; // 將新節點加在末端
break;
}

// 如果該數字應該插入在中間某個位置
if (n->number < ptr->next->number)
{
n->next = ptr->next; // 新節點指向後續節點
ptr->next = n; // 前一個節點指向新節點
break;
}
}
}
}

// 印出鏈結串列中的數字
for (node *ptr = list; ptr != NULL; ptr = ptr->next)
{
printf("%i\n", ptr->number);
}

// 釋放記憶體
node *ptr = list;
while (ptr != NULL)
{
node *next = ptr->next; // 保存下一個節點的位置
free(ptr); // 釋放當前節點
ptr = next; // 移動到下一個節點
}
}


raw-image


raw-image


從中間插入新的數值

raw-image


陣列與鏈結串列的 Big O 複雜度

從效能角度來看,陣列和鏈結串列在不同操作上的表現各有所長:

  • 插入或刪除元素:對於陣列來說,插入或刪除元素可能需要移動大部分的元素,因此是 O(n) 的時間複雜度;而鏈結串列只需要調整指標,因此是 O(1)。
  • 找特定位置的元素:陣列可以直接通過索引快速找到任意位置的元素,這是 O(1) 的操作;而鏈結串列則需要遍歷所有節點來找到目標位置,要從第一個開始找陣列,因此是 O(n)。


留言
avatar-img
越南放大鏡 X 下班資工系
60會員
108內容數
雙重身份:越南放大鏡 X 下班資工系 政大東南亞語言學系是我接觸越南語的起點,畢業後找越南外派工作的生活跟資訊時,發現幾乎都是清單式的分享,很難身歷其境。所以我希望「越南放大鏡」可以帶讀者看到更多細節和深入的觀察。 - 下班資工系則是自學資工系的課程內容,記錄實際操作的過程,學習理論的過程。希望可以跟讀者一起成長。
2025/04/24
本系列文章將循序漸進地介紹 JavaScript 的核心概念,從基礎語法到進階應用,例如非同步程式設計和 React 基礎。內容淺顯易懂,並使用生活化的比喻幫助讀者理解,搭配程式碼範例,適合 JavaScript 初學者學習。
Thumbnail
2025/04/24
本系列文章將循序漸進地介紹 JavaScript 的核心概念,從基礎語法到進階應用,例如非同步程式設計和 React 基礎。內容淺顯易懂,並使用生活化的比喻幫助讀者理解,搭配程式碼範例,適合 JavaScript 初學者學習。
Thumbnail
2025/04/21
本文介紹行動通訊網路的演進歷史,從1G到5G,並說明ITU與3GPP在制定通訊規格上的重要角色,以及5G的三大關鍵應用場景:URLLC、eMBB和mMTC。
Thumbnail
2025/04/21
本文介紹行動通訊網路的演進歷史,從1G到5G,並說明ITU與3GPP在制定通訊規格上的重要角色,以及5G的三大關鍵應用場景:URLLC、eMBB和mMTC。
Thumbnail
2025/04/11
這篇文章說明網路的七層模型、IP 位址、通訊埠、TCP/UDP 協定、HTTP 協定、HTTP 狀態碼以及 WebSocket,並解釋它們之間的關係與互動方式。文中包含許多圖表和範例,幫助讀者理解這些網路概念。
Thumbnail
2025/04/11
這篇文章說明網路的七層模型、IP 位址、通訊埠、TCP/UDP 協定、HTTP 協定、HTTP 狀態碼以及 WebSocket,並解釋它們之間的關係與互動方式。文中包含許多圖表和範例,幫助讀者理解這些網路概念。
Thumbnail
看更多
你可能也想看
Thumbnail
我每週都會為自己設計一趟小旅行,像是給日常的一個深呼吸。準備著簡單的行李,在導航上設定好今天想去的地方,播放一張剛好符合心情的歌單,一場逃離日常的小旅行就此展開。 說走就走的自由很浪漫,但背後的現實是,從加油、路途中補給、到抵達目的地的小花費,每一筆都需要精打細算,才能不讓放鬆變成負擔。好在有玉山
Thumbnail
我每週都會為自己設計一趟小旅行,像是給日常的一個深呼吸。準備著簡單的行李,在導航上設定好今天想去的地方,播放一張剛好符合心情的歌單,一場逃離日常的小旅行就此展開。 說走就走的自由很浪漫,但背後的現實是,從加油、路途中補給、到抵達目的地的小花費,每一筆都需要精打細算,才能不讓放鬆變成負擔。好在有玉山
Thumbnail
本文介紹玉山銀行推出的玉山 Unicard,是一張非常符合「小資族、學生、上班族都好上手」的高回饋信用卡!三種回饋方案自由切換,行動支付、百貨、旅遊、百大指定通路全面涵蓋,新戶最高享 7.5% 回饋。回饋透明、操作簡單,非常推薦學生、小資族與上班族。
Thumbnail
本文介紹玉山銀行推出的玉山 Unicard,是一張非常符合「小資族、學生、上班族都好上手」的高回饋信用卡!三種回饋方案自由切換,行動支付、百貨、旅遊、百大指定通路全面涵蓋,新戶最高享 7.5% 回饋。回饋透明、操作簡單,非常推薦學生、小資族與上班族。
Thumbnail
信用卡如今已是現代人日常消費的必需品。回顧其誕生,竟源於一段用餐忘記帶錢的窘境。本文將帶您瞭解信用卡的故事,並介紹「玉山Unicard」,一張涵蓋百大通路、提供彈性回饋的信用卡,尤其適合追求方便與高回饋的消費者。文章將分享誠品生活、全盈+PAY等實際使用情境,並提供新戶申辦優惠資訊。
Thumbnail
信用卡如今已是現代人日常消費的必需品。回顧其誕生,竟源於一段用餐忘記帶錢的窘境。本文將帶您瞭解信用卡的故事,並介紹「玉山Unicard」,一張涵蓋百大通路、提供彈性回饋的信用卡,尤其適合追求方便與高回饋的消費者。文章將分享誠品生活、全盈+PAY等實際使用情境,並提供新戶申辦優惠資訊。
Thumbnail
玉山銀行新推出的Unicard信用卡你發現了嗎?主打可透過玉山Wallet App,每月自由切換簡單選、任意選及UP選三種方案,讓你依照消費習慣擁有不同的回饋方案。其中我自己很喜歡它百大指定消費中的Line Pay行動支付,能讓我以最簡單的方式獲得最高的回饋!同時文中更分享我實測的眉角,快來看下去!
Thumbnail
玉山銀行新推出的Unicard信用卡你發現了嗎?主打可透過玉山Wallet App,每月自由切換簡單選、任意選及UP選三種方案,讓你依照消費習慣擁有不同的回饋方案。其中我自己很喜歡它百大指定消費中的Line Pay行動支付,能讓我以最簡單的方式獲得最高的回饋!同時文中更分享我實測的眉角,快來看下去!
Thumbnail
本章節示範透過「陣列索引」和「指標運算」兩種方式來存取同一個二維陣列 a,並印出相同的數值以及對應的位址,以說明它們其實指向的是同一塊連續的記憶體空間。本文將依序解釋各段程式碼,並示範可能的執行結果與背後原理。
Thumbnail
本章節示範透過「陣列索引」和「指標運算」兩種方式來存取同一個二維陣列 a,並印出相同的數值以及對應的位址,以說明它們其實指向的是同一塊連續的記憶體空間。本文將依序解釋各段程式碼,並示範可能的執行結果與背後原理。
Thumbnail
本章將介紹 C 語言的陣列 (Arrays),這是一種 連續儲存多個相同類型變數 的數據結構。透過陣列,我們可以有效管理與操作大量數據,並應用在 數據處理、排序、搜尋與多維數據存取 等情境中。
Thumbnail
本章將介紹 C 語言的陣列 (Arrays),這是一種 連續儲存多個相同類型變數 的數據結構。透過陣列,我們可以有效管理與操作大量數據,並應用在 數據處理、排序、搜尋與多維數據存取 等情境中。
Thumbnail
陣列(Array)是 JavaScript 中用來儲存一組有序資料的集合。 陣列可以包含各種資料型別的值,例如數字、字串、布林值,甚至其他陣列或物件。了解陣列的基本操作是編寫高效 JavaScript 程式碼的重要基礎。
Thumbnail
陣列(Array)是 JavaScript 中用來儲存一組有序資料的集合。 陣列可以包含各種資料型別的值,例如數字、字串、布林值,甚至其他陣列或物件。了解陣列的基本操作是編寫高效 JavaScript 程式碼的重要基礎。
Thumbnail
在 C 語言中,陣列的大小固定且使用連續記憶體空間,插入新元素可能不便。鏈結串列則提供了靈活性,可以在不需要連續記憶體的情況下,輕鬆插入新節點。本文將探討陣列與鏈結串列各自的特點,並對比它們在插入與查找操作上的 Big O 複雜度,讓讀者瞭解在不同情境下使用的最佳資料結構選擇。
Thumbnail
在 C 語言中,陣列的大小固定且使用連續記憶體空間,插入新元素可能不便。鏈結串列則提供了靈活性,可以在不需要連續記憶體的情況下,輕鬆插入新節點。本文將探討陣列與鏈結串列各自的特點,並對比它們在插入與查找操作上的 Big O 複雜度,讓讀者瞭解在不同情境下使用的最佳資料結構選擇。
Thumbnail
在上一篇文章中,我們介紹了「陣列」的基本使用方式。本篇將帶你深入探討 C 語言中字串的運作原理,了解如何以陣列形式儲存字串。此外,我們還會介紹如何將英文字母透過 ASCII 表轉換成數值,並說明其在電腦中的實際應用。最後,解析 Command Line Argument(命令列參數)的使用方法。
Thumbnail
在上一篇文章中,我們介紹了「陣列」的基本使用方式。本篇將帶你深入探討 C 語言中字串的運作原理,了解如何以陣列形式儲存字串。此外,我們還會介紹如何將英文字母透過 ASCII 表轉換成數值,並說明其在電腦中的實際應用。最後,解析 Command Line Argument(命令列參數)的使用方法。
Thumbnail
👨‍💻簡介 陣列就像是一個儲存相同類型資料的容器,你可以想像成裝滿了一樣東西的盒子,每個東西都叫做陣列元素。這種類型可以是基本的,像是整數或字串,也可以是你自己定義的型別。不過陣列有個限制,就是大小一旦確定就無法改變。在Go語言裡,陣列的長度也是型別的一部分。
Thumbnail
👨‍💻簡介 陣列就像是一個儲存相同類型資料的容器,你可以想像成裝滿了一樣東西的盒子,每個東西都叫做陣列元素。這種類型可以是基本的,像是整數或字串,也可以是你自己定義的型別。不過陣列有個限制,就是大小一旦確定就無法改變。在Go語言裡,陣列的長度也是型別的一部分。
Thumbnail
Array 在記憶體中連續分配,而且元素類型是一樣的,長度不變 優點:讀取快,可以使用座標訪問 缺點:新增、刪除慢 記憶體: 📷 範例程式碼: ArrayList 不定長度,在記憶體中連續分配的,元素沒有類型限制,任何元素都是當成object處理,如果是值類型,會有裝箱的操作 優點:讀取快 缺點:
Thumbnail
Array 在記憶體中連續分配,而且元素類型是一樣的,長度不變 優點:讀取快,可以使用座標訪問 缺點:新增、刪除慢 記憶體: 📷 範例程式碼: ArrayList 不定長度,在記憶體中連續分配的,元素沒有類型限制,任何元素都是當成object處理,如果是值類型,會有裝箱的操作 優點:讀取快 缺點:
Thumbnail
C# 陣列 – (C#教學) – Array為程式設計中最基本元素之一. 陣列就是用一個variable記下多個同類的值(記憶體中的位置), 以供日後所調用. 相關頁面: C# List – 學會List的5種基本應用方法 – 初始化, 加入值, 更新值, 刪除值, foreach迴圈
Thumbnail
C# 陣列 – (C#教學) – Array為程式設計中最基本元素之一. 陣列就是用一個variable記下多個同類的值(記憶體中的位置), 以供日後所調用. 相關頁面: C# List – 學會List的5種基本應用方法 – 初始化, 加入值, 更新值, 刪除值, foreach迴圈
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News