數據結構—>帶你深入了解單鏈表(基礎篇)

?作者簡介:大家好,我是橘橙黃又青,一個想要與大家共同進步的男人😉😉

🍎個人主頁:橘橙黃又青-CSDN博客

前面我們學習了順序表,今天我們來學習與順序表類似的單鏈表

1.🍎什么是鏈表

概念:鏈表是?種物理存儲結構上?連續、?順序的存儲結構,數據元素的邏輯順序是通過鏈表
中的指針鏈接次序實現的 。
鏈表的結構跟???廂相似,淡季時?次的?廂會相應減少,旺季時?次的?廂會額外增加?節。只需要將???的某節?廂去掉/加上,不會影響其他?廂,每節?廂都是獨?存在的。

?廂是獨?存在的,且每節?廂都有??。想象?下這樣的場景,假設每節?廂的??都是鎖上的狀 態,需要不同的鑰匙才能解鎖,每次只能攜帶?把鑰匙的情況下如何從?頭?到?尾?
最簡單的做法:每節?廂?都放?把下?節?廂的鑰匙
那在在鏈表?,每節“?廂”是什么樣的呢?
與順序表不同的是,鏈表?的每節"?廂"都是獨?申請下來的空間,我們稱之為“結點/節點”
節點的組成主要有兩個部分: 當前節點要保存的數據和保存下?個節點的地址(指針變量)。
圖中指針變量 plist保存的是第?個節點的地址,我們稱plist此時“指向”第?個節點,如果我們希
望plist“指向”第?個節點時,只需要修改plist保存的內容為0x0012FFA0。

?

結合前?學到的結構體知識,我們可以給出每個節點對應的結構體代碼:
假設當前保存的節點為整形:
代碼:
struct SListNode
{int data; //節點數據struct SListNode* next; //指針變量?保存下?個節點的地址
};
當我們想要保存?個整型數據時,實際是向操作系統申請了?塊內存,這個內存不僅要保存整型數
據,也需要保存下?個節點的地址(當下?個節點為空時保存的地址為空)。
當我們想要從第?個節點?到最后?個節點時,只需要在前?個節點拿上下?個節點的地址(下?個 節點的鑰匙)就可以了。

?2. 🍎鏈表的打印

給定的鏈表結構中,如何實現節點從頭到尾的打印?

看圖:

代碼:

//打印
void SLTPrint(SLTNode* phead) {SLTNode* pcur = phead;while (pcur){printf("%d->", pcur->data);pcur = pcur->next;}printf("NULL\n");
}
//開辟空間
SLTNode* SLTBuyNode(SLTDataType x) {SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL) {perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = NULL;return newnode;
}

這樣就可以了,?這里補充說明:

1、鏈式機構在邏輯上是連續的,在物理結構上不?定連續
2、節點?般是從堆上申請的
3、從堆上申請來的空間,是按照?定策略分配出來的,每次申請的空間可能連續,可能不連續

?前面簡單學習打印,接下來我們進入單鏈表的增,刪,查。

3,🍎單鏈表的基礎應用

?這里我們介紹一下我的單鏈表代碼:

typedef int SLTDataType;
//鏈表是由節點組成
typedef struct SListNode
{SLTDataType data;struct SListNode* next;
}SLTNode;

創建一個這樣的空間鏈表:?

3.1🍎鏈表的尾插

代碼展示:

void SLTPushBack(SLTNode** pphead, SLTDataType x) {assert(pphead);SLTNode* newnode = SLTBuyNode(x);//鏈表為空,新節點作為pheadif (*pphead == NULL) {*pphead = newnode;return;}//鏈表不為空,找尾節點//創建代跑變量SLTNode* ptail = *pphead;while (ptail->next){ptail = ptail->next;}//ptail就是尾節點ptail->next = newnode;
}

?圖片展示:

值得注意的是開辟的空間next是指向nuLL的?

?

3.2🍎鏈表的頭插

代碼展示:

void SLTPushFront(SLTNode** pphead, SLTDataType x) {assert(pphead);SLTNode* newnode = SLTBuyNode(x);//newnode *ppheadnewnode->next = *pphead;*pphead = newnode;
}

圖片展示:?

3.3🍎鏈表的頭刪

代碼:

void SLTPopFront(SLTNode** pphead) {assert(pphead);//鏈表不能為空assert(*pphead);//讓第二個節點成為新的頭//把舊的頭結點釋放掉SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next;
}

思路:

3.4🍎鏈表的尾刪

代碼:

void SLTPopBack(SLTNode** pphead) {assert(pphead);//鏈表不能為空assert(*pphead);//鏈表不為空//鏈表只有一個節點,有多個節點if ((*pphead)->next == NULL) {free(*pphead);*pphead = NULL;return;}SLTNode* ptail = *pphead;SLTNode* prev = NULL;while (ptail->next)//找尾節點{prev = ptail;ptail = ptail->next;}prev->next = NULL;//銷毀尾結點free(ptail);ptail = NULL;
}

?把尾節點釋放掉,置為空

3.5🍎鏈表的查找

代碼:

//查找
SLTNode* SLTFind(SLTNode** pphead, SLTDataType x) {assert(pphead);//遍歷鏈表SLTNode* pcur = *pphead;while (pcur) //等價于pcur != NULL{if (pcur->data == x) {return pcur;}pcur = pcur->next;}//沒有找到return NULL;
}

這個也是很簡單,遍歷鏈表,有就返回,無返回空。?

3.6🍎鏈表在指定位置之前插入數據

代碼:

//在指定位置之前插入數據
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x) {assert(pphead);assert(pos);//要加上鏈表不能為空assert(*pphead);SLTNode* newnode = SLTBuyNode(x);//pos剛好是頭結點if (pos == *pphead) {//頭插SLTPushFront(pphead, x);return;}//pos不是頭結點的情況SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}//prev -> newnode -> posprev->next = newnode;newnode->next = pos;
}

思路:

?

插入代碼就在上面啦。?

?

3.7🍎鏈表在指定位置之后插入數據

代碼:

//在指定位置之后插入數據
void SLTInsertAfter(SLTNode* pos, SLTDataType x) {assert(pos);SLTNode* newnode = SLTBuyNode(x);//pos newnode pos->nextnewnode->next = pos->next;pos->next = newnode;
}

但是這里要注意了:

思路:

?

3.8🍎刪除pos節點

?代碼:

//刪除pos節點
void SLTErase(SLTNode** pphead, SLTNode* pos) {assert(pphead);assert(*pphead);assert(pos);//pos剛好是頭結點,沒有前驅節點,執行頭刪if (*pphead == pos) {//頭刪SLTPopFront(pphead);return;}SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}//prev pos pos->nextprev->next = pos->next;free(pos);pos = NULL;
}

?思路:

3.9🍎刪除pos之后的節點

代碼:

//刪除pos之后的節點
void SLTEraseAfter(SLTNode* pos) {assert(pos);//pos->next不能為空assert(pos->next);//pos  pos->next  pos->next->nextSLTNode* del = pos->next;pos->next = pos->next->next;free(del);del = NULL;
}

思路:

?

3.10🍎銷毀鏈表

堆銷毀很重要,創建鏈表也要學會銷毀鏈表

?代碼:

//銷毀鏈表
void SListDesTroy(SLTNode** pphead) {assert(pphead);assert(*pphead);SLTNode* pcur = *pphead;while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}

解釋:

創建帶跑指針,把下一個節點地址記錄下來,釋放原來第一個節點空間,再把下一個節點地址給帶跑指針。

好啦,我們今天就講到這里,喜歡就點一個贊吧,感謝觀看。

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

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

相關文章

鴻蒙Harmony應用開發—ArkTS聲明式開發(通用屬性:透明度設置)

設置組件的透明度。 說明: 從API Version 7開始支持。后續版本如有新增內容,則采用上角標單獨標記該內容的起始版本。 opacity opacity(value: number | Resource) 設置組件的不透明度。 卡片能力: 從API version 9開始,該接口…

香橙派AIpro快速上手指南

1 前言 作為業界首款基于昇騰深度研發的AI開發板,Orange Pi AIpro無論在外觀上、性能上還是技術服務支持上都非常優秀,其8/20TOPS澎湃算力是目前開發板市場中所具備的最大算力,能覆蓋生態開發板者的主流應用場景,讓用戶實踐各種創…

深入理解Redis中的漸進式Rehash技術

1. 引言 Redis是一款高性能的鍵值存儲系統,被廣泛應用于緩存、隊列、計數器等場景,因其快速、穩定的特性備受開發者青睞。在Redis的背后,有著許多復雜的數據結構和算法支撐著其高效運行,而其中之一就是Rehash操作。 Rehash是Redis中的一個關鍵操作,負責在數據量增加時對…

Web自動化測試平臺開發---Automated_platform

一、項目簡介 歷時一個假期,Automated_platform 第一版完工,是一款基于po模式的自動化測試平臺,采用后端技術為DjangoceleryRabbitMQmysql 配置mysql數據庫,進行數據遷移后,運行項目后,即可成功訪問http://127.0.0.1:8…

5. 升級 Spring Boot(Upgrading Spring Boot)

5. 升級 Spring Boot(Upgrading Spring Boot) 項目 wiki 提供如何從 Spring Boot 早期版本升級的說明。請按照 release notes 部分查找要升級到的版本。 升級說明總是版本說明的第一部分。如果您的版本落后一個以上,請確保您已經查看了所跳…

【軟考】數據結構之隊列和棧

目錄 1.例題一1.1題目1.2 題目截圖1.3 題目分析 1.例題一 1.1題目 輸出受限的雙端隊列是指元素可以從隊列的兩端輸入,但只能從隊列的一端輸出,如下圖所示,若有e1,e2,e3,e4依次進入輸出受限的雙端隊列&…

Nginx-location匹配規則

每次配置Nginx的時候,不是多個這匹配不上就是那匹配不上,多個斜線少個斜線的,然后頭疼,尤其多層代理之后,真是瘋狂掉頭發 #mermaid-svg-Z1ScpZFefeixtnn3 {font-family:"trebuchet ms",verdana,arial,sans-s…

Linux——進程控制(一)進程的創建與退出

目錄 一、進程創建 1.寫時拷貝 2.創建多個進程 二、進程終止 1.main函數的返回值 2.bash中的$? 3.自定義退出碼 4.C語言的錯誤碼 5.錯誤碼與退出碼的區別 6.代碼異常終止 7.exit函數 8.總結 一、進程創建 在之前,我們學過linux中的非常重要的函數——…

Git 將dev1.0分支的某些commit合并到dev分支上

前言:dev1.0是新開發的需求內容,但是部分熱更內容在此分支提交,如今需要把熱更的內容發到dev環境,但是dev1.0新需求未開發完畢,不可更新到dev環境。 現在在dev1.0分支 git pull #拉取當前分支最新內容git log #查看最…

3. 文字陰影

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>文字陰影</title><style>*{margin: …

速賣通店鋪營銷秘籍:如何巧妙運用活動提升轉化率

對于速賣通賣家而言&#xff0c;想要提升店鋪的成交率&#xff0c;除了依賴付費推廣外&#xff0c;更重要的是如何通過店鋪營銷來吸引和留住潛在買家。今天&#xff0c;我們就來深入探討一下速賣通店鋪營銷的幾個關鍵策略。 首先&#xff0c;我們要明確一點&#xff0c;速賣通平…

IDEA中的Structure模塊使用詳解

IDEA中的Structure模塊使用詳解 類方法的展示 從左往右介紹&#xff1a; 1、最開頭的 m 標識是表示為方法&#xff0c;如出現 f 標識則表示為屬性&#xff1b; 2、m后面跟著的是方法或者屬性的訪問修飾符&#xff1a; #紅色關閉的鎖表示為private&#xff1b; #圓圈表示不帶…

使用Docker搭建一款實用的個人IT工具箱——It-Tools

作為程序員&#xff0c;在日常工作中&#xff0c;需要借助一些工具來提高我們工作效率&#xff0c;IT-Tools是為開發人員度身打造的一套便捷在線工具。它提供全面功能&#xff0c;使開發者能以更高效方式完成任務。經由IT-Tools&#xff0c;開發人員能輕松應對各類技術挑戰&…

qt QRadioButton 及QButtonGroup 使用

QRadioButton 放在組合框QGroupBox中&#xff0c;再點擊時&#xff0c;即使有多個QRadioButton按鈕&#xff0c;同時選中的也就只有一個。 如下圖所示&#xff0c; 對于多個QRadioButton&#xff0c;每個按鈕都寫一個槽函數是不太明智的選擇&#xff0c;需要將QRadioButton放在…

海外服務器ping丟包怎么辦?

一般跨境企業比如說跨境電商、游戲等等都會有海外各個節點服務器的需求&#xff0c;包括對海外服務器的需求。當使用海外服務器時 &#xff0c;難免會出現一些問題&#xff0c;比如說丟包。那么&#xff0c;當海外服務器丟包的話&#xff0c;該如何處理呢&#xff1f; 說到丟包…

「MySQL」增刪查改

在操作數據庫中的表時&#xff0c;需要先使用該數據庫&#xff1a; use database;新增 創建表 先用 use 指定一個數據庫,然后使用 create 新增一個表 比如建立一個學生表 mysql> use goods; mysql> create table student(-> name varchar(4),-> age int,-> …

Compose 介紹

Compose 介紹 Android Compose 是 Google 官方推出的用于構建原生 Android UI 的現代工具包。它使用 Kotlin 語言編寫&#xff0c;可以幫助開發人員更輕松、更快速地創建精美、響應式和高性能的 Android 應用。 Compose 的優勢 聲明式 UI&#xff1a; Compose 使用聲明式 UI…

IIS部署.Net 7項目

&#x1f468; 作者簡介&#xff1a;大家好&#xff0c;我是Taro&#xff0c;前端領域創作者 ?? 個人主頁&#xff1a;唐璜Taro &#x1f680; 支持我&#xff1a;點贊&#x1f44d;&#x1f4dd; 評論 ??收藏 文章目錄 前言一、發布項目二、解決發布失敗1.發布失敗2.托管…

深入理解計算機系統筆記

1.1 嵌套的數組 當我們創建數組的數組時&#xff0c;數組分配和引用的一般原則也是成立的。 例如&#xff0c;聲明 int A[5][3]; 等價于下面的聲明 typedef int row3_t[3]; row3_t A[5] 要訪問多維數組的元素&#xff0c;編譯器會以數組起始為基地址&#xff0c; (可能需…

【Ai生態開發】Spring AI上架,打造專屬業務大模型,AI開發再也不是難事!

大家好 這里是蘇澤 后端是工作 ai是興趣 對于ai的產生我的立場是擁抱ai的 是希望拿他作為提升能力的工具 那么這一篇帶大家來學習如何使用ai打造一個專屬的業務大模型 需求 就是說假設現在有一個 商城系統 里面有查詢訂單的api和獲取商品購買方式的api 用戶只需要輸入 “…