【初階數據結構】鏈表的柔光之美

目錄

一、為什么需要鏈表?

二、鏈表與數組的對比

三、鏈表節點定義

四、鏈表基本操作

1. 創建鏈表

2. 插入節點

頭插法(時間復雜度O(1))

尾插法(時間復雜度O(n))

3. 刪除節點

4. 遍歷鏈表

五、進階操作

1. 反轉鏈表(迭代法)

2. 檢測環(快慢指針法)

六、內存管理要點

七、常見錯誤排查

八、鏈表變體

十、完整示例代碼

總結

路過的佬們點點關注哦~

你們的鼓勵是我前進的動力~


一、為什么需要鏈表?

在C語言程序設計中,數組是最基礎的數據結構,但它存在明顯的局限性:

  • 固定長度,無法動態擴展

  • 插入/刪除元素需要大量數據移動

  • 內存空間要求連續

鏈表(Linked List)通過動態內存分配指針連接完美解決了這些問題。每個元素(節點)包含:

  1. 數據域 - 存儲實際數據

  2. 指針域 - 存儲下一個節點的地址

二、鏈表與數組的對比

三、鏈表節點定義

typedef struct Node {int data;           // 數據域struct Node *next;  // 指針域
} Node;

四、鏈表基本操作

1. 創建鏈表

Node* createList(int data) {Node* head = (Node*)malloc(sizeof(Node));if (head == NULL) {printf("內存分配失敗!");exit(1);}head->data = data;head->next = NULL;return head;
}

2. 插入節點

頭插法(時間復雜度O(1))
void insertAtHead(Node** head, int data) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = data;newNode->next = *head;*head = newNode;
}
尾插法(時間復雜度O(n))
void insertAtTail(Node* head, int data) {Node* current = head;while (current->next != NULL) {current = current->next;}Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = data;newNode->next = NULL;current->next = newNode;
}

3. 刪除節點

void deleteNode(Node** head, int key) {Node *temp = *head, *prev;// 刪除頭節點if (temp != NULL && temp->data == key) {*head = temp->next;free(temp);return;}// 查找待刪除節點while (temp != NULL && temp->data != key) {prev = temp;temp = temp->next;}if (temp == NULL) return;// 解除鏈接并釋放內存prev->next = temp->next;free(temp);
}

4. 遍歷鏈表

void printList(Node* head) {Node* current = head;while (current != NULL) {printf("%d -> ", current->data);current = current->next;}printf("NULL\n");
}

五、進階操作

1. 反轉鏈表(迭代法)

void reverseList(Node** head) {Node *prev = NULL;Node *current = *head;Node *next = NULL;while (current != NULL) {next = current->next;  // 保存下一個節點current->next = prev;  // 反轉指針prev = current;        // 前移prevcurrent = next;        // 前移current}*head = prev;
}

2. 檢測環(快慢指針法)

int hasCycle(Node *head) {Node *slow = head, *fast = head;while (fast != NULL && fast->next != NULL) {slow = slow->next;fast = fast->next->next;if (slow == fast) {return 1;  // 存在環}}return 0;  // 無環
}

六、內存管理要點

必須檢查malloc返回值

Node* newNode = (Node*)malloc(sizeof(Node));
if (newNode == NULL) {// 處理內存分配失敗
}

及時釋放內存

void freeList(Node* head) {Node* temp;while (head != NULL) {temp = head;head = head->next;free(temp);}
}

避免野指針

free(temp);
temp = NULL;  // 釋放后立即置空

七、常見錯誤排查

  1. 段錯誤(Segmentation Fault)

    • 訪問已釋放的內存

    • 指針未初始化就使用

  2. 內存泄漏

    • 使用valgrind工具檢測

    • 確保每個malloc都有對應的free

  3. 邏輯錯誤

    • 忘記更新頭指針

    • 指針操作順序錯誤

八、鏈表變體

雙向鏈表

typedef struct DNode {int data;struct DNode *prev;struct DNode *next;
} DNode;

循環鏈表

// 尾節點指向頭節點
head->next = head;

帶頭節點的鏈表

  • 統一操作邏輯

  • 簡化邊界條件處理

九、應用場景

  1. 實現棧/隊列

  2. 多項式運算

  3. 文件系統目錄結構

  4. 圖結構的鄰接表

  5. 內存管理系統

十、完整示例代碼

#include <stdio.h>
#include <stdlib.h>typedef struct Node {int data;struct Node* next;
} Node;// [此處插入上述各個函數實現]int main() {Node* list = createList(5);insertAtHead(&list, 2);insertAtTail(list, 8);printf("原始鏈表: ");printList(list);  // 輸出: 2 -> 5 -> 8 -> NULLreverseList(&list);printf("反轉后: ");printList(list);  // 輸出: 8 -> 5 -> 2 -> NULLdeleteNode(&list, 5);printf("刪除后: ");printList(list);  // 輸出: 8 -> 2 -> NULLfreeList(list);return 0;
}

總結

鏈表是C語言中最基礎也最重要的數據結構之一,掌握鏈表需要理解:

  • 指針的操作原理

  • 動態內存管理機制

  • 數據結構與算法的關系

建議通過以下方式鞏固學習:

  1. 手寫實現所有鏈表操作

  2. 使用調試工具觀察內存變化

  3. 嘗試實現雙向鏈表等變體

  4. 解決LeetCode鏈表相關題目(如206反轉鏈表、141環形鏈表)

掌握鏈表將為學習更復雜的數據結構(樹、圖等)打下堅實基礎。

路過的佬們點點關注哦~

你們的鼓勵是我前進的動力~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/bicheng/71847.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/71847.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/71847.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《論湖倉一體架構及其應用》審題技巧 - 系統架構設計師

軟考論文寫作框架 一、考點概述 “湖倉一體架構及其應用”這一論題&#xff0c;主要考察了考生對現代數據管理系統中湖倉一體架構的理解、應用及問題解決能力。隨著5G、大數據、人工智能、物聯網等技術的快速發展&#xff0c;企業數據的管理需求正發生深刻變化。傳統的數據管…

MybatisPlus-擴展功能-枚舉處理器

在Mybatis里有一個叫TypeHandler的類型處理器&#xff0c;我們常見的PO當中的這些成員變量的數據類型&#xff0c;它都有對應的處理器&#xff0c;因此它就能自動實現這些Java數據類型與數據庫類型的相互轉換。 它里面還有一個叫EnumOrdinalTypeHandler的枚舉處理器&#xff0…

北京大學第二彈《DeepSeek提示詞工程和落地場景》

大家好&#xff0c;我是吾鳴。 之前給大家分享過北京大學出品的DeepSeek教程《DeepSeek與AIGC應用》&#xff0c;今天吾鳴發現北京大學又出第二版教程了&#xff0c;教程的名稱叫做《DeepSeek提示詞工程和落地場景》&#xff0c;在此分享給大家。文末有完整版PDF下載地址。 教程…

deepseek自動化代碼生成

使用流程 效果第一步&#xff1a;注冊生成各種大模型的API第二步&#xff1a;注冊成功后生成API第三步&#xff1a;下載vscode在vscode中下載agent&#xff0c;這里推薦使用cline 第四步&#xff1a;安裝完成后&#xff0c;設置模型信息第一步選擇API provider&#xff1a; Ope…

322.零錢兌換

class Solution(object):def coinChange(self, coins, amount):""":type coins: List[int]:type amount: int:rtype: int"""n len(coins) dp [float(inf)]*(amount 1) # 初始值為正無窮大dp[0] 0 # 一定要初始化為0if amount 0:return 0 …

ARM Cortex-M處理器中的MSP和PSP

在ARM Cortex-M系列處理器中&#xff0c;MSP&#xff08;主堆棧指針&#xff09;和PSP&#xff08;進程堆棧指針&#xff09;是兩種不同的堆棧指針&#xff0c;主要用于實現堆棧隔離和提升系統可靠性。以下是它們的核心區別和應用場景&#xff1a; 1. 基本定義 MSP&#xff08;…

交換機與路由器連接方式

交換機和路由器連接的三種主要方式如下&#xff1a; 一、直連連接 這是最簡單直接的連接方式。通過一根網線將交換機的一個端口與路由器的一個LAN端口相連。這種連接方式適用于小型網絡&#xff0c;其中交換機負責局域網內部的數據交換&#xff0c;而路由器則負責將內部網絡連接…

Python代碼片段-Excel導入到MongoDB

有一次遇到一個需求&#xff0c;需要把Excel的數據導入到MongoDB中&#xff0c;表面上感覺就是導入數據很簡單&#xff0c;但實際操作后&#xff0c;發現是比較麻煩的一個事情&#xff0c;一般圖形化的工具對于MongoDB而言&#xff0c;導入選項都是json的&#xff0c;根本沒有E…

axios幾種請求類型的格式

Axios 是一個基于 Promise 的 HTTP 客戶端&#xff0c;廣泛用于瀏覽器和 Node.js 中發送 HTTP 請求。它支持多種請求格式&#xff0c;包括 GET、POST、PUT、DELETE 等。也叫RESTful 目錄 一、axios幾種請求類型的格式 1、get請求 2、post請求 3、put請求 4、delete請求 二…

手寫系列——MoE網絡

參考&#xff1a; MOE原理解釋及從零實現一個MOE&#xff08;專家混合模型&#xff09;_moe代碼-CSDN博客 MoE環游記&#xff1a;1、從幾何意義出發 - 科學空間|Scientific Spaces 深度學習之圖像分類&#xff08;二十八&#xff09;-- Sparse-MLP(MoE)網絡詳解_sparse moe…

Linux的基礎指令和環境部署,項目部署實戰(下)

目錄 上一篇&#xff1a;Linxu的基礎指令和環境部署&#xff0c;項目部署實戰&#xff08;上&#xff09;-CSDN博客 1. 搭建Java部署環境 1.1 apt apt常用命令 列出所有的軟件包 更新軟件包數據庫 安裝軟件包 移除軟件包 1.2 JDK 1.2.1. 更新 1.2.2. 安裝openjdk&am…

【藍橋杯】第十五屆省賽大學真題組真題解析

【藍橋杯】第十五屆省賽大學真題組真題解析 一、智能停車系統 1、知識點 &#xff08;1&#xff09;flex-wrap 控制子元素的換行方式 屬性值有&#xff1a; no-wrap不換行wrap伸縮容器不夠則自動往下換行wrap-reverse伸縮容器不夠則自動往上換行 &#xff08;2&#xff0…

flink operator v1.10對接華為云對象存儲OBS

1 概述 flink operator及其flink集群&#xff0c;默認不直接支持華為云OBS&#xff0c;需要在這些java程序的插件目錄放一個jar包&#xff0c;以及修改flink配置后&#xff0c;才能支持集成華為云OBS。 相關鏈接參考&#xff1a; https://support.huaweicloud.com/bestpracti…

免費PDF工具

Smallpdf.com - A Free Solution to all your PDF Problems Smallpdf - the platform that makes it super easy to convert and edit all your PDF files. Solving all your PDF problems in one place - and yes, free. https://smallpdf.com/#rappSmallpdf.com-解決您所有PD…

去中心化技術P2P框架

中心化網絡與去中心化網絡 1. 中心化網絡 在傳統的中心化網絡中&#xff0c;所有客戶端都通過一個中心服務器進行通信。這種網絡拓撲結構通常是一個星型結構&#xff0c;其中服務器作為中心節點&#xff0c;每個客戶端只能與服務器通信。如果客戶端之間需要通信&#xff0c;必須…

muduo源碼閱讀:linux timefd定時器

?timerfd timerfd 是Linux一個定時器接口&#xff0c;它基于文件描述符工作&#xff0c;并通過該文件描述符的可讀事件進行超時通知。可以方便地與select、poll和epoll等I/O多路復用機制集成&#xff0c;從而在沒有處理事件時阻塞程序執行&#xff0c;實現高效的零輪詢編程模…

Pinia 3.0 正式發布:全面擁抱 Vue 3 生態,升級指南與實戰教程

一、重大版本更新解析 2024年2月11日&#xff0c;Vue 官方推薦的狀態管理庫 Pinia 迎來 3.0 正式版發布&#xff0c;本次更新標志著其全面轉向 Vue 3 技術生態。以下是開發者需要重點關注的升級要點&#xff1a; 1.1 核心變更說明 特性3.0 版本要求兼容性說明Vue 支持Vue 3.…

【圖像處理 --- Sobel 邊緣檢測的詳解】

Sobel 邊緣檢測的詳解 目錄 Sobel 邊緣檢測的詳解1. 梯度計算2. 梯度大小3. 梯度方向4. 非極大值抑制5. 雙閾值處理6. 在 MATLAB 中實現 Sobel 邊緣檢測7.運行結果展示8.關鍵參數解釋9.實驗與驗證 Sobel 邊緣檢測是一種經典的圖像處理算法&#xff0c;用于檢測圖像中的邊緣。它…

LeetCode 熱題100 15. 三數之和

LeetCode 熱題100 | 15. 三數之和 大家好&#xff0c;今天我們來解決一道經典的算法題——三數之和。這道題在 LeetCode 上被標記為中等難度&#xff0c;要求我們從一個整數數組中找到所有不重復的三元組&#xff0c;使得三元組的和為 0。下面我將詳細講解解題思路&#xff0c…

基因組組裝中的術語1——from HGP

Initial sequencing and analysis of the human genome | Nature 1&#xff0c;分層鳥槍法測序hierarchical shotgun sequencing