數據結構(四)內核鏈表、棧與隊列

一、內核鏈表基礎

1. 什么是 Linux 內核鏈表?

Linux 內核鏈表是一種高效的 雙向循環鏈表,廣泛應用于內核模塊開發中,用于管理數據結構。每個節點通過指針連接前一個和后一個元素,實現插入和刪除的高性能。

2. 鏈表的定義與初始化

在 Linux 內核中,鏈表的實現依賴于 struct list_head 結構體,定義在頭文件 <linux/list.h> 中:

struct list_head {
struct list_head *next, *prev;
};

為了在自定義結構體中集成鏈表,只需在結構體中包含 list_head 成員即可:

struct my_data {
int value;
struct list_head list;
}

鏈表初始化使用如下宏:

LIST_HEAD(my_list); // 靜態初始化
// 或者
INIT_LIST_HEAD(&my_list); // 動態初始化

這兩種方式都將 list.nextlist.prev 指向自身,構成一個空的循環鏈表。

注意:內核鏈表已經將增刪查改封裝好了,開發者只需要聚焦于數據部分。


3. 內核鏈表設計思想

  • 普通鏈表將數據和節點結構緊耦合。

  • 內核鏈表則通過將鏈表節點作為結構體中的一個字段,從而實現結構體與鏈表解耦。

常用宏如下:

  • offsetof():用于計算某個成員在結構體中的偏移量。

  • container_of():用于通過結構體成員地址獲取整個結構體指針。

#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))


4. 常用鏈表操作宏與函數

功能宏 / 函數名稱說明
添加節點list_add / list_add_tail添加到鏈表頭/尾
刪除節點list_del將節點從鏈表中移除
遍歷鏈表list_for_each遍歷每一個節點(通用)
遍歷鏈表list_for_each_entry遍歷包含結構體的鏈表

5. 使用鏈表需注意的要點

  • 內存管理:新增節點前需手動分配內存;刪除節點后應釋放。

  • 線程安全:多線程環境下需加鎖。

  • 性能考量:鏈表適合插入/刪除頻繁場景,但查找效率低。


二、棧(Stack)

1. 基本定義

棧是一種 只允許在一端(棧頂)進行插入和刪除操作 的線性結構,遵循 后進先出(LIFO) 原則。

在 C 語言中,我們通常用動態內存(堆區)來實現線性棧結構。

2. 結構特點

  • 棧頂(top):允許插入/刪除的一端。

  • 棧底(bottom):固定不動的一端。

  • 空棧:棧中無任何數據元素。

3. 棧的類型

  • 滿增棧:棧滿時從低地址向高地址增長。

  • 空減棧:從高地址向低地址擴展。

  • 實際實現時通常選擇一種邏輯來處理棧頂移動。

📌 示例說明

棧空間從底部開始增長,壓棧操作使 top++,出棧使 top--。如果 top 達到容量限制,表示棧已滿。

4. 棧的應用場景

  • 遞歸求解 / 回溯問題

  • 表達式求值(符號優先級)

  • 函數調用管理(程序棧幀)


5. 棧的基本操作代碼

#include <stdio.h>
#include "stack.h"
#include <stdlib.h>Stack *creatStack()
{Stack *pstack = malloc(sizeof(Stack));if(pstack == NULL){printf("malloc error\n");return NULL;}pstack->ptop = NULL;pstack->clen = 0;return pstack;
}int IsEmptyStack(Stack *pstack)
{return NULL == pstack->ptop;
}
int pushStack(Stack *pstack, DataType data)
{StNode *pnode = malloc(sizeof(StNode));if(NULL == pnode){printf("malloc error\n");return -1;}pnode->data = data;pnode->pnext = NULL;pnode->pnext = pstack->ptop;pstack->ptop = pnode;pstack->clen++;return 1;
}/*** @brief 出棧,且出棧之前保存棧頂的元素,通過主函數定義的dadatype類型返回改后的數值* * @param pstack 棧頭指針* @param data 返回的棧頂元素的值* @return int 成功出棧返回1,失敗為0*/
int popStack(Stack *pstack, DataType *data)
{if(IsEmptyStack(pstack)){return -1;}StNode *temp = pstack->ptop;*data = temp->data;pstack->ptop = temp->pnext;free(temp);pstack->clen--;return 1;
}/*** @brief Get the Stack Top object* * @param pstack * @param data * @return int */
int getStackTop(Stack *pstack, DataType *data)
{if(IsEmptyStack(pstack)){return -1;}*data = pstack->ptop->data;return 1;
}void printStack(Stack *pstack)
{if(IsEmptyStack(pstack)){return ;}StNode *temp = pstack->ptop;while(temp){printf("%d ", temp->data);temp = temp->pnext;}puts("");return ;
}void destroyStack(Stack **pstack)
{StNode *temp = (*pstack)->ptop;while(temp){(*pstack)->ptop = temp->pnext;free(temp);temp = (*pstack)->ptop;}free(*pstack);*pstack = NULL;
}

三、隊列(Queue)

1. 基本定義

隊列是一種**先進先出(FIFO)**的數據結構,特點是:

  • 隊尾(tail) 進入數據

  • 隊頭(head) 移除數據

2. 隊列的應用場景

  • 緩沖區管理

  • 數據包調度

  • 多任務之間的通信機制


3. 循環隊列(環形隊列)

為避免頻繁移動數據,可將隊列邏輯設計為循環結構。即:利用數組,頭尾指針移動時利用求余操作形成環形效果。

next = (tail + 1) % MAX_LEN;

判斷條件:
隊列狀態條件
隊空head == tail
隊滿(tail + 1) % MAX == head

4. 隊列的類型

  • 順序隊列(數組實現)

  • 鏈式隊列(鏈表實現,擴展性強)


5. 鏈表型隊列的代碼

#include <stdio.h>
#include "linkqueue.h"
#include <stdlib.h>LQueue *creatQLink()
{LQueue *plink = malloc(sizeof(LQueue));if(NULL == plink){fprintf(stderr, "malloc error\n");return NULL;}plink->phead = NULL;plink->ptail = NULL;plink->clen = 0;return plink;
}int isEmptyLQueue(LQueue *plink)
{return NULL == plink->phead;
}int pushLQueue(LQueue *plink, DataType data)
{LQNode *pnode = malloc(sizeof(LQNode));if(pnode == NULL){fprintf(stderr, "malloc error\n");return -1;}pnode->data = data;pnode->pnext = NULL;if(isEmptyLQueue(plink)){plink->phead = pnode;plink->ptail = pnode;plink->clen++;}else{plink->ptail->pnext = pnode;plink->ptail = pnode;plink->clen++;}return 0;
}int popLQueue(LQueue *plink)
{if(isEmptyLQueue(plink)){fprintf(stderr,"is empty lqueue\n");return -1;}LQNode *temp = plink->phead;plink->phead = temp->pnext;if(NULL == temp->pnext){plink->ptail = NULL;}free(temp);plink->clen--;return 0;
}LQNode* getLQueueHeadNode(LQueue *plink)
{if(isEmptyLQueue(plink)){fprintf(stderr, "empty Lqueue\n");return NULL;}return plink->phead;
}void printLQueue(LQueue *plink)
{if(isEmptyLQueue(plink)){fprintf(stderr, "empty lqueue\n");return ;}LQNode *temp = plink->phead;while(temp){printf("%d ", temp->data);temp = temp->pnext;}puts("");return ;
}void destroyLQueue(LQueue **plink)
{LQNode *temp = (*plink)->phead;while(temp){(*plink)->phead = temp->pnext;free(temp);temp = (*plink)->phead;}free(*plink);*plink = NULL;return ;
}

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

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

相關文章

軟考信息安全工程師11月備考

目前是在職備考&#xff0c;主業是移動端開發工程師。第一個月(8.4-9.6)&#xff0c;將分享完下面所有章節內容&#xff0c;平均不到兩天更新一節1.網絡信息安全概述2.網絡攻擊原理與常用方法3.密碼學基本理論4.網絡安全體系與網絡安全模型5.物理與環境安全技術6.認證技術與原理…

使用DrissionPage實現xhs筆記自動翻頁并爬取筆記視頻、圖片

使用DrissionPage實現xhs筆記自動翻頁并爬取筆記視頻、圖片 聲明: 本文章中所有內容僅供學習交流使用,不用于其他任何目的,不提供完整代碼,抓包內容、敏感網址、數據接口等均已做脫敏處理,嚴禁用于商業用途和非法用途,否則由此產生的一切后果均與作者無關! 本文章未經…

使用 input 上傳文件, 選擇文件后再次修改文件再上傳失敗( <input type=“file“ /> 自定義上傳)

業務實際需求&#xff1a;點擊【選擇】按鈕先選擇文件&#xff0c;展示文件的詳情&#xff1a;類型&#xff0c;大小&#xff0c;日期......點擊【上傳】按鈕這個時候才去上傳文件如圖&#xff1a;BUG復現&#xff1a;點擊上傳文件后發現xlsx文件有些數據沒填寫&#xff0c;然后…

Win11 下解決 VScode/Trae 插件加載慢, 整個 VScode/Trae 很卡

最近在使用 Trae 寫代碼, 突然變得很卡, 尤其是插件系統, 比如我打開插件的面板, 以及比如我想預覽一下寫好的 .md 文件 (已安裝了 Markdown Preview Enhanced 插件), 這些都要好幾分鐘才能打開. 最初以為是 Trae 壞掉了, 然后重啟 Trae 不管用, 再重啟電腦居然也不管用, 接著…

微型導軌:智能家居抽屜的智能化應用

當智能家居從“功能堆砌”轉向“體驗升級”&#xff0c;微型導軌憑借超薄結構、靜音運行與精準定位能力&#xff0c;成為隱藏式設計、自動化交互的核心部件&#xff0c;讓家具“動”得優雅且可靠。智能掃地機器人&#xff1a;微型導軌被應用于邊刷的伸縮調節機構&#xff0c;能…

百套易語言教程、易語言視頻教程【易語言編程入門教程】

百套易語言教程、易語言視頻教程【易語言編程入門教程】 易語言輔助教程&#xff08;愛易編程論壇講師 24課講師&#xff1a;遠航 9課愛易編程論壇講師&#xff1a;愛易、小Call 8課&#xff09;.rar 時光論壇易語言全套教程【易語言零基礎易語言抓包易語言填表】完整版.rar 易…

nlp-詞匯分析

目錄 一、語言中的詞匯 1、詞的形態學 2、詞的詞性 二、詞語規范化 1、詞語切分 2、詞形還原 3、詞干提取 三、中文分詞 1、概述 2、基于最大匹配的中文分詞 3、基于線性鏈條件隨機場的中文分詞 4、基于感知器的中文分詞 詞序列預測 模型參數學習 特征定義 5、…

Kafka ISR機制和Raft區別:副本數優化的秘密

Kafka的ISR機制和像Raft這樣的傳統基于Quorum&#xff08;法定人數&#xff09;的協議之間的區別確實很微妙&#xff0c;但也非常重要。讓我們來分析一下為什么ISR可以減少所需的副本數量。在采用ISR模型和&#xff08;f1&#xff09;個副本數的配置下&#xff0c;一個Kafka分區…

新手向:GitCode疑難問題診療

Git疑難問題診療引言在軟件開發過程中&#xff0c;版本控制系統&#xff08;VCS&#xff09;是不可或缺的工具&#xff0c;而Git以其分布式架構、強大的分支管理能力和高效的性能成為行業標準。然而&#xff0c;隨著項目復雜度的提升&#xff0c;Git的使用也可能遇到各種疑難問…

電子電氣架構 ---如何煥新升級為 48V 電氣架構

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

JavaScript判斷數字方法

在JavaScript中&#xff0c;判斷一個值是否為數字有多種場景&#xff0c;以下是常見方法及適用情況&#xff1a;1. 嚴格判斷數字類型&#xff08;排除NaN&#xff09;使用 typeof 結合 !isNaN()&#xff0c;確保值是 number 類型且非 NaN&#xff1a;javascriptfunction isNumb…

C++編程之旅-- -- --始探門庭的求知漫溯(二)

目錄引用內聯函數(C11)auto關鍵字基于范圍的for循環指針空值---nullptr引用 引用&#xff1a;指將變量以另一個名稱來展現的。它并非是一個新變量而是一個別名&#xff0c;它們同指一塊內存空間。就如古時那些有字的人,亦或者是周樹人&#xff0c;你說魯迅是不是周樹人呢&…

wordpress網站的“管理員郵箱地址”有什么用?

在WordPress網站的“設置”-“常規”中設置的“管理員郵箱地址”有多種用途&#xff0c;以下是詳細介紹&#xff1a; 一、用戶注冊相關 密碼找回功能 當網站用戶忘記密碼時&#xff0c;他們會通過點擊登錄頁面上的“忘記密碼”鏈接來重置密碼。WordPress系統會向管理員郵箱地…

202506 電子學會青少年等級考試機器人六級實際操作真題

更多內容和歷年真題請查看網站&#xff1a;【試卷中心 -----> 電子學會 ----> 機器人技術 ----> 六級】 網站鏈接 青少年軟件編程歷年真題模擬題實時更新 202506 青少年等級考試機器人實操真題六級 一、實際操作 1. 主題&#xff1a;姿態傳感器交互步進電機左右…

Centos 安裝 redis

1.下載redis&#xff0c;這個自己去網上找吧。2.上傳文件&#xff0c;redis-7.4.1.tar.gz3.解壓&#xff1a;執行 tar -xf redis-7.4.1.tar.gz在進行安裝之前&#xff0c;檢查一下有沒有make、gcc、python3、沒有的話全部 yum install。安裝完之后&#xff0c;如果報一下錯誤&a…

算法訓練營DAY55 第十一章:圖論part05

并查集理論基礎 背景 當我們需要判斷兩個元素是否在同一個集合里的時候&#xff0c;我們就要想到用并查集。 并查集主要有兩個功能&#xff1a; 將兩個元素添加到一個集合中。判斷兩個元素在不在同一個集合 原理講解 從代碼層面&#xff0c;我們如何將兩個元素添加到同一個…

docker相關操作記錄

1.docker清理服務器上面沒有用到的鏡像#刪除本地鏡像 docker rmi $(docker images -q) #強制刪除本地鏡像 docker rmi $(docker images -q) -f2.docker查看日志docker logs c36c56e4cfa3 (容器id)3.所有運行或沒有運行的鏡像 docker ps -a4、停止container&#xff0c;這樣才…

LInux基礎學習筆記七

/dev/zero和/dev/null 是什么/dev/zero&#xff1a;一個零設備文件&#xff0c;讀取時會不斷返回\0字節&#xff08;零值字節&#xff09;&#xff0c;常用于創建空文件或格式化/dev/null&#xff1a;一個空設備文件&#xff0c;寫入它的內容會被丟棄&#xff0c;相當于“黑洞”…

軟件架構:系統結構的頂層設計與戰略約束

軟件架構&#xff1a;系統結構的頂層設計與戰略約束軟件架構是軟件系統的“骨架”與“憲法”&#xff0c;它定義了系統的根本性組織結構&#xff0c;包括構成系統的關鍵構件、它們之間的組織關系、交互機制、約束原則以及指導性決策。它決定了系統在性能、可擴展性、可靠性、可…

基于spring boot的個人博客系統

2 開發技術 3 2.1 VUE框架 3 2.2 Mysql數據庫 3 2.3 Spring Boot框架 3 2.4 layui介紹 4 本程序在設計結構選擇上首選B/S&#xff0c;也是為了滿足程序今后升級便利&#xff0c;以及程序低維護成本的要求。本程序的網絡拓撲設計也會在下圖展示&#xff0c;通過圖形的方式來描述…