讓雙向鏈表不在云里霧里

又來博客留下我的足跡了,哈哈哈,這次是對于雙向鏈表的理解

目錄

創建雙向鏈表:

申請結點:

雙向鏈表初始化:

雙向鏈表插入結點:

雙向鏈表刪除結點:

雙向鏈表的打印:

雙向鏈表的查找:

雙向鏈表的銷毀:

結語:


在雙向鏈表中有頭雙向循環,無頭雙向循環,有頭雙向不循環,無頭雙向不循環,而我將要介紹的是有頭雙向循環,別看名字長,其實就是只紙老虎,只要我們理解它的結構,問題自然迎刃而解了結構圖如下:

創建雙向鏈表:

從上面的結構圖我們不然發現,我們創建需要定義什么指針域和數據域

typedef int LTDataType;
typedef struct ListNode
{struct ListNode* prev;//指針域struct ListNode* next;//指針域LTDataType data;//數據域
}LTNode;

申請結點:

與單鏈表代碼差不多,將其指針域置空,就不再過多贅述

LTNode* BuyNode(LTDataType x)
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));//申請空間if (newnode == NULL){perror("malloc fail");return;}newnode->data = x;//賦值newnode->next = NULL;newnode->prev = NULL;return newnode;//返回創建的結點
}

雙向鏈表初始化:

我們只需將自己連向自己,下一個指向上一個,上一個指向下一個,如圖:

LTNode* LTInit()
{LTNode* phead = BuyNode(-1);//傳空,為phead申請空間phead->next = phead->prev;phead->prev = phead->next;return phead;//返回頭結點
}

雙向鏈表插入結點:

頭插:

我們先將新結點的后指針指向第一個結點的數據域,第一個結點的前指針指向新結點的數據域,新結點的前指針亦然,可能文字可能形容有點模糊,所以我們看下圖:

void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = BuyNode(x);LTNode* Next = phead->next;//保存下一個結點的地址,防止丟失//新結點與后結點鏈接newnode->next = Next;Next->prev = newnode;//新結點與頭節點鏈接newnode->prev = phead;phead->next = newnode;
}

溫馨提示:如果沒有保存下一個結點的地址,則需先跟后結點鏈接,在與頭結點相連

尾插:

雙鏈表尾插相對于單鏈表的尾插來說要容易許多,因為我們可以輕松找到尾,然后改變指針指向即可,如下圖:

void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = BuyNode(x);//創建新結點LTNode* tail = phead->prev;//找尾//尾結點與新結點相連newnode->prev = tail;tail->next = newnode;//新結點與頭結點相連newnode->next = phead;phead->prev = newnode;
}

在指定位置插入:

我們通常會在指定位置之前插入,找到指定位置前一個,然后改變指針方向即可,如圖:

void LTInsert(LTNode* phead, LTNode* pos, LTDataType x)
{assert(phead);LTNode* newnode = BuyNode(x);LTNode* front = pos->prev;//找到指定位置前一個結點//新結點與指定結點相連newnode->next = pos;pos->prev = newnode;//新節點與指定結點前一個結點相連front->next = newnode;newnode->prev = front;
}

雙向鏈表刪除結點:

頭刪:

我們先要判斷鏈表是否為空,如果為空就不用刪除了;因為之后要釋放刪除的結點,所以我們還需保存一下,這樣就可以了

bool LTEmpty(LTNode* phead)
{return phead == phead->next;
}
void LTPopFront(LTNode* phead)
{assert(phead);assert(!LTEmpty(phead));//判斷鏈表是否為空LTNode* del = phead->next;LTNode* Next = phead->next->next;//第一結點的下一個結點與頭結點相連Next->prev = phead;phead->next = Next;free(del);//釋放掉這個結點del = NULL;
}

尾刪:

尾刪就比較容易了,將尾結點釋放,然后改變指針指向,就這樣完成了^ - ^

void LTPopBack(LTNode* phead)
{assert(phead);assert(phead != phead->next);//或assert(!LTEmpty(phead))LTNode* tail = phead->prev;LTNode* Pretail = tail->prev;//頭節點與尾結點的前一個結點相連Pretail->next = phead;phead->next = Pretail;free(tail);//釋放尾結點tail = NULL;
}

在指定位置刪除:

找到要刪除結點的前一個和后一個,然后兩個結點相互鏈接,這樣就能夠刪除了,如圖:

void LTErase(LTNode* phead, LTNode* pos)
{assert(phead);LTNode* front = pos->prev;//找到前結點LTNode* back = pos->next;//找到后結點//前結點和后結點相連front->next = back;back->prev = front;free(pos);//釋放指定節點pos = NULL;
}

雙向鏈表的打印:

提到打印,我們會用到遍歷循環,那循環結束的標志是什么呢?有一個好主意,我們可以先從第一個結點開始打印,然后向后循環遍歷,直至遍歷到頭結點,循環結束^_^,如下圖:

void LTPrint(LTNode* phead)
{LTNode* begin = phead->next;while (begin != phead)//循環繼續條件{printf("%d<=>", begin->data);begin = begin->next;}printf("\n");
}

雙向鏈表的查找:

遍歷一遍鏈表,然后找要查找的元素

LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){if (cur->data == x)return cur;cur = cur->next;}return NULL;//沒找到
}

雙向鏈表的銷毀:

將動態申請的空間釋放掉,并循環釋放每一個結點,防止內存泄漏的風險

void LTDestroy(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;LTNode* next = cur->next;while (cur != phead){LTNode* next = cur->next;//防止找不到下一個結點free(cur);cur = next;}free(phead);//釋放頭結點
}

結語:

紙短情長,不盡依依,謝謝觀看!

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

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

相關文章

java虛擬機(JVM)以及各種參數詳解

Java 虛擬機&#xff08;JVM&#xff09;提供了許多參數來調整其行為和性能&#xff0c;以便更好地適應不同的應用場景。理解和使用這些參數對于優化 Java 應用程序的性能非常重要。以下是一些常用的 JVM 參數及其詳細說明&#xff1a; 1. 內存管理參數 -Xms<size>&…

如何搭配 AI 量化策略選股

AI 量化選股策略結合了 技術指標、基本面數據、市場情緒&#xff0c;利用 機器學習、深度學習、因子分析 等方法&#xff0c;提高選股精準度和交易決策效率。下面介紹 如何搭配 AI 量化策略選股。 1. AI 量化選股的核心方法 AI 量化選股主要依靠 數據驅動&#xff0c;包括&…

Python 爬蟲:一文掌握 SVG 映射反爬蟲

更多內容請見: 爬蟲和逆向教程-專欄介紹和目錄 文章目錄 1. SVG 概述1.1 SVG的優點1.1 映射反爬蟲的原理2. SVG 映射反爬蟲的示例3. 應對 SVG 映射反爬蟲的方法3.1 解析 SVG 圖像3.2 處理自定義字體3.3 使用 OCR 技術3.4 動態生成 SVG 的處理4. 實戰案例4.1 使用 SVG 映射顯示…

前端工程化之前端工程化詳解 包管理工具

前端工程化詳解 & 包管理工具 前端工程化什么是前端工程化前端工程化發展腳手架能力 體驗度量規范流程效能流程扭轉 穩定性建設針對整體穩定性建設 可監控&#xff1a;前端監控系統 包管理工具npm包詳解package.jsonname 模塊名description 模塊描述信息keywords&#xff1…

《Python實戰進階》No24: PyAutoGUI 實現桌面自動化

No24: PyAutoGUI 實現桌面自動化 摘要 PyAutoGUI 是一個跨平臺的桌面自動化工具&#xff0c;能夠模擬鼠標點擊、鍵盤輸入、屏幕截圖與圖像識別&#xff0c;適用于重復性桌面任務&#xff08;如表單填寫、游戲操作、批量文件處理&#xff09;。本集通過代碼截圖輸出日志的實戰形…

一周學會Flask3 Python Web開發-SQLAlchemy查詢所有數據操作-班級模塊

鋒哥原創的Flask3 Python Web開發 Flask3視頻教程&#xff1a; 2025版 Flask3 Python web開發 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 我們來新建一個的藍圖模塊-班級模塊&#xff0c;后面可以和學生模塊&#xff0c;實現一對多的數據庫操作。 blueprint下新建g…

Neural Architecture Search for Transformers:A Survey

摘要 基于 Transformer 的深度神經網絡架構因其在自然語言處理 (NLP) 和計算機視覺 (CV) 領域的各種應用中的有效性而引起了極大的興趣。這些模型是多種語言任務&#xff08;例如情緒分析和文本摘要&#xff09;的實際選擇&#xff0c;取代了長短期記憶 (LSTM) 模型。視覺 Tr…

TCP 全連接隊列 內核層理解socket

TCP 全連接隊列 理解 listen 的第二個參數 int listen(int sockfd, int backlog);backlog 參數表示 全連接隊列&#xff08;accept 隊列&#xff09;的最大長度。 那什么是全連接隊列呢&#xff1f; 三次握手 & accept() 處理流程 客戶端發送 SYN&#xff0c;服務器收到并…

程序化廣告行業(18/89):交易模式與關鍵概念解析

程序化廣告行業&#xff08;18/89&#xff09;&#xff1a;交易模式與關鍵概念解析 大家好呀&#xff01;一直以來&#xff0c;我都在深入研究程序化廣告這個充滿挑戰與機遇的領域&#xff0c;在學習過程中收獲了很多&#xff0c;也迫不及待想和大家分享。寫這篇博客&#xff…

在離線情況下如何使用 Python 翻譯文本

以下是在離線環境下使用Python進行文本翻譯的兩種主流方案&#xff0c;包含本地模型部署和輕量級詞典兩種方法&#xff1a; 方案一&#xff1a;使用本地神經網絡翻譯模型&#xff08;推薦&#xff09; # 安裝依賴&#xff08;需提前下載&#xff09; # pip install argos-tra…

OpenEuler-22.03-LTS上利用Ansible輕松部署MySQL 5.7

一、需求 使用ansible自動化部署mysql二進制部署mysql部署mysql并創建JDBC用戶 二、環境信息 本文涉及的代碼&#xff0c;配置文件地址&#xff1a; 鏈接&#xff1a;百度網盤 請輸入提取碼 提取碼&#xff1a;1g6y 軟件名稱版本備注Ansible2.9.27All modules — Ansible Doc…

基于javaweb的SpringBoot農資商城購物商城系統設計與實現(源碼+文檔+部署講解)

技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、小程序、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;免費功能設計、開題報告、任務書、中期檢查PPT、系統功能實現、代碼編寫、論文編寫和輔導、論…

angular打地鼠

說明&#xff1a;我計劃用angular做一款打地鼠的小游戲&#xff0c; 打地鼠游戲實現文檔 &#x1f3ae; 游戲邏輯 ?游戲場景 采用 3x3 網格布局的 9 個地鼠洞?核心機制 地鼠隨機從洞口彈出點擊有效目標獲得積分30 秒倒計時游戲模式 ?難度系統 簡單模式&#xff1a;生成間…

博客網站(springboot)整合deepseek實現在線調用

&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389; 歡迎訪問的個人博客&#xff1a;https://swzbk.site/&#xff0c;加好友&#xff0c;拉你入福利群 &#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389; 1、de…

Kubernetes 單節點集群搭建

Kubernetes 單節點集群搭建教程 本人嘗試基于Ubuntu搭建一個單節點K8S集群&#xff0c;其中遇到各種問題&#xff0c;最大的問題就是網絡&#xff0c;各種鏡像源下載不下來&#xff0c;特此記錄&#xff01;注意&#xff1a;文中使用了幾個鏡像&#xff0c;將看來可能失效導致安…

【PTA題目解答】7-3 字符串的全排列(20分)next_permutation

1.題目 給定一個全由小寫字母構成的字符串&#xff0c;求它的全排列&#xff0c;按照字典序從小到大輸出。 輸入格式: 一行&#xff0c;一個字符串&#xff0c;長度不大于8。 輸出格式: 輸出所有全排列&#xff0c;每行一種排列形式&#xff0c;字典序從小到大。 輸入樣例…

專題三0~n-1中缺失的數字

1.題目 給一個數組&#xff0c;單調性是遞增的&#xff0c;需要找到缺失的數字&#xff0c;加上這個數字就變為等差數組了。 2.算法原理 這里用二分來解決&#xff0c;而二段性是根據下標區分&#xff0c;臨界值前的數字于下標相對應&#xff0c;臨界值后的于下標相差1&#x…

【圖像處理】ISP(Image Signal Processor) 圖像處理器的用途和工作原理?

ISP&#xff08;圖像信號處理器&#xff09;是數字影像設備的“視覺大腦”&#xff0c;負責將傳感器捕獲的原始電信號轉化為我們看到的高清圖像。以下從用途和工作原理兩方面通俗解析&#xff1a; 一、ISP的核心用途&#xff1a;讓照片“更像眼睛看到的” 提升畫質&#xff1a…

python學習筆記-mysql數據庫操作

現有一個需求&#xff0c;調用高德api獲取全國縣級以上行政區數據并保存為json文件&#xff0c;使用python獲取&#xff1a; import requests import json# 高德API Key api_key "your_api_key"# 調用行政區域查詢API def fetch_districts():url f"https://r…

Redisson 實現分布式鎖源碼淺析

大家好&#xff0c;我是此林。 今天來分享Redisson分布式鎖源碼。還是一樣&#xff0c;我們用 問題驅動 的方式展開講述。 1. redis 中如何使用 lua 腳本&#xff1f; Redis內置了lua解釋器&#xff0c;lua腳本有兩個好處&#xff1a; 1. 減少多次Redis命令的網絡傳輸開銷。…