數據結構與算法-線性表-雙向鏈表(Double Linked List)

1 線性表

1.4 雙向鏈表(Double Linked List)

雙向鏈表的結點中有兩個指針域,一個指向直接后繼,另一個指向直接前驅,主要是為了解決前向查找的問題。

雙向鏈表結構:

在這里插入圖片描述

書籍和視頻教程都只講解了插入和刪除的算法,這里也實現這兩個算法。

一些常量和元素和前面類似,結點需要多一個前驅指針,結點結構代碼如下:

// 雙向鏈表的結點結構
typedef struct DuLNode
{ElemType data;                // 結點數據,ElemType類型struct DuLNode *prior, *next; // 指向下一個結點的指針
} DuLNode, *DuLinkList;           // DuLinkList 是指向 DuLNode 結構的指針類型,表示單鏈表的頭結點指針

另外為了方便查看插入的效果,需要初始化雙向鏈表,和插入一些數據方便測試,這里使用尾插法進行處理,尾插法的實現和前面基本類似,就是新結點要設置相應的前驅:

// 尾插法創建雙向鏈表
Status CreateListTail(DuLinkList *L, int n)
{*L = (DuLinkList)malloc(sizeof(DuLNode)); // 創建頭結點if (*L == NULL){return OVERFLOW;}(*L)->next = NULL; // 初始化頭結點的next指針為NULLDuLNode *p = *L; // p 指向頭結點for (int i = 1; i <= n; i++){// 創建一個新結點DuLNode *newNode = (DuLNode *)malloc(sizeof(DuLNode));if (!newNode) // 如果內存分配失敗return OVERFLOW;newNode->data.x = i; // 將數據賦值給新結點// 插入新結點newNode->next = NULL; // 新結點的后繼指針置空newNode->prior = p;   // 新結點的前驅指針指向當前結點p->next = newNode;    // 當前結點的后繼指針指向新結點p = newNode;          // p 指向新插入的結點}return OK;
}

還有插入和刪除都涉及另外一個算法——獲取第 i 個結點,這里補充一下:

// 獲取第 i 個結點,并返回結點指針
DuLNode *GetElem_Dul(DuLinkList *L, int i)
{if (i < 1) // i 值不合法return NULL;DuLNode *p = (*L)->next; // 從頭結點的下一個結點開始遍歷int j = 1;               // 計數器,從1開始while (p != NULL && j < i) // 遍歷到第i個結點 并且 當前結點不為空{p = p->next; // 移動到下一個結點j++;}if (p == NULL || j > i)return NULL;return p;
}

1.4.1 插入

插入的步驟要比單鏈表多設置幾個指針指向,主要的難點在于順序很重要,如果順序不對,可能導致實際的指針被提前修改,無法獲取到對應的結點。

【算法步驟】

  1. 將新結點的前驅指針指向當前結點的前驅結點。①
  2. 將當前結點的前驅結點的后繼指針指向新結點。②
  3. 將新結點的后繼指針指向當前結點。③
  4. 將當前結點的前驅指針指向新結點。④

在這里插入圖片描述

【代碼實現】

// 插入結點,在 i-1 和 i 之間插入一個結點,新結點的位置就是 i
Status ListInsert(DuLinkList *L, int i, ElemType e)
{DuLNode *p;if (!(p = GetElem_Dul(L, i))) // 獲取第 i 個結點return ERROR;DuLNode *newNode = (DuLNode *)malloc(sizeof(DuLNode)); // 創建新結點if (newNode == NULL)return OVERFLOW;newNode->data = e;         // 設置新結點的數據newNode->prior = p->prior; // 將新結點的前驅指針指向當前結點的前驅結點p->prior->next = newNode;  // 將當前結點的前驅結點的后繼指針指向新結點newNode->next = p;         // 將新結點的后繼指針指向當前結點p->prior = newNode;        // 將當前結點的前驅指針指向新結點return OK;
}

【算法分析】

時間復雜度主要受 GetElem_Dul 影響,因此為 O(n)

1.4.2 刪除

【算法步驟】

  1. 將前驅結點的后繼指針指向當前結點的后繼結點。①
  2. 如果當前結點不是最后一個結點,將后繼結點的前驅指針指向當前結點的前驅結點。②

在這里插入圖片描述

【代碼實現】

// 刪除第 i 個結點
Status ListDelete(DuLinkList *L, int i)
{DuLNode *p;if (!(p = GetElem_Dul(L, i))) // 獲取第 i 個結點return ERROR;p->prior->next = p->next;      // 將前驅結點的后繼指針指向當前結點的后繼結點if (p->next != NULL)           // 如果當前結點不是最后一個結點p->next->prior = p->prior; // 將后繼結點的前驅指針指向當前結點的前驅結點free(p); // 釋放當前結點內存return OK;
}

【算法分析】

時間復雜度主要受 GetElem_Dul 影響,因此為 O(n)

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

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

相關文章

甘特圖實例 dhtmlxGantt.js

本文介紹了如何使用dhtmlxGantt庫創建一個基礎的甘特圖示例&#xff0c;并對其進行漢化和自定義配置。首先&#xff0c;通過引入dhtmlxgantt.css和dhtmlxgantt.js文件初始化甘特圖。接著&#xff0c;通過設置gantt.i18n.setLocale("cn")實現核心文本的漢化&#xff0…

C++23 新增扁平化關聯容器詳解

文章目錄 一、引言已有關聯容器回顧新容器的引入原因 二、std::flat_set定義與特性代碼示例適用場景 三、std::flat_multiset定義與特性代碼示例適用場景 四、std::flat_map定義與特性代碼示例適用場景 五、std::flat_multimap定義與特性代碼示例適用場景 六、與其他容器的比較…

使用zap,對web應用/API接口 做安全檢測

https://www.zaproxy.org/getting-started/ 檢測方法 docker pull ghcr.io/zaproxy/zaproxy:stable# 執行baseline測試 docker run -t ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \ -t https://baseline.yeshen.org# 執行api測試 docker run -t ghcr.io/zaproxy/zaproxy…

Qt—模態與非模態對話框

Qt—模態與非模態對話框 核心概念 ?模態對話框??&#xff1a;強制用戶優先處理當前窗口&#xff0c;阻塞指定范圍的用戶交互。?非模態對話框??&#xff1a;允許用戶自由切換窗口&#xff0c;無交互限制。 一、模態對話框類型與行為 1. 應用級模態&#xff08;Applica…

Axure高保真CRM客戶關系管理系統原型

一套出色的CRM&#xff08;客戶關系管理&#xff09;系統&#xff0c;無疑是企業管理者掌控客戶動態、提升銷售業績的得力助手。今天&#xff0c;就為大家介紹一款精心打造的Axure高保真CRM客戶關系管理系統原型模板&#xff0c;助你輕松開啟高效客戶管理之旅。 這款CRM原型模…

【羊圈——狀壓 + DP / 記憶化搜索DP】

題目 一般DP代碼&#xff08;注意&#xff0c;這里只能向外推(起始狀態是f(1,0)&#xff0c;不能向內推&#xff08;不然會導致之前的羊圈被割裂&#xff09;&#xff09; #include <bits/stdc.h> using namespace std;const int MAX_N 210; const int MAX_M 16;int n…

講解Mysql InnoDB的MVCC

1. 定義 MVCC是多版本并發控制&#xff08;Multi - Version Concurrency Control&#xff09;的縮寫。它是InnoDB存儲引擎實現高并發控制的一種機制。在數據庫系統中&#xff0c;多個事務可能會同時對數據進行讀寫操作&#xff0c;而MVCC通過為數據行保存多個版本來解決并發事務…

ZeroMQ Sockets介紹及應用示例

1. 概念解釋 ZeroMQ Sockets提供了一種類標準套接字&#xff08;socket-like&#xff09;的 API&#xff0c;是消息導向的通信機制&#xff0c;基于 TCP/UDP 等傳輸層協議&#xff0c;但封裝了底層細節&#xff08;如連接管理、消息路由、緩沖區等&#xff09;&#xff0c;提供…

語音合成之十五 語音合成(TTS)分句生成拼接時的響度一致性問題:現狀、成因與對策

語音合成&#xff08;TTS&#xff09;分句生成拼接時的響度一致性問題&#xff1a;現狀、成因與對策 引言&#xff1a;分段式文本轉語音中的響度一致性挑戰業界對響度差異問題的認知拼接語音片段中響度變化的根本原因分段拼接的固有挑戰各片段預測韻律特征的差異文本特征和模型…

Android中Binder驅動作用?

Binder驅動的作用與核心功能 Binder驅動是Android系統中實現進程間通信&#xff08;IPC&#xff09;的核心底層組件&#xff0c;它工作于Linux內核層&#xff0c;負責管理跨進程通信的建立、數據傳輸、資源同步等關鍵任務。以下是其核心作用及實現細節&#xff1a; 1. ??進程…

網絡學習-TCP協議(七)

一、TCP協議 TCP&#xff08;Transmission Control Protocol&#xff0c;傳輸控制協議&#xff09;是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。 1、三次握手 客戶端&#xff1a; 1、先發起連接&#xff0c;發送SYN置1&#xff0c;seqnum12345(隨機值)----半連接…

【Python 基礎與實戰】從基礎語法到項目應用的全流程解析

&#xff08;1&#xff09;列表和元組的區別是什么?如何從列表創建元組?如何從元組創建列表? 列表和元組的區別&#xff1a; 可變性&#xff1a;列表是可變的&#xff0c;即可以對列表進行元素的增、刪、改操作。例如&#xff0c;可以使用append()方法添加元素&#xff0c;r…

Docker部署Zookeeper集群

簡介 ZooKeeper 是一個開源的分布式協調服務&#xff0c;由 Apache 軟件基金會開發和維護。它主要用于管理和協調分布式系統中的多個節點&#xff0c;以解決分布式環境下的常見問題&#xff0c;如配置管理、服務發現、分布式鎖等。ZooKeeper 提供了一種可靠的機制&#xff0c;…

【學習筆記】Sophus (Python) 使用文檔

以下是一份針對 Sophus 庫的 Python 使用文檔&#xff0c;涵蓋基礎概念、安裝方法、核心功能及代碼示例。內容圍繞 SO3&#xff08;3D旋轉群&#xff09;和 SE3&#xff08;3D剛體變換群&#xff09;展開&#xff0c;適合機器人學、SLAM、三維幾何等領域。 Sophus (Python) 使用…

計算機圖形學:(三)MVP變換擴展

Three.js WebGL允許把JavaScript和OpenGL 結合在一起運用&#xff0c;但使用WebGL原生的API來寫3D程序非常的復雜&#xff0c;同時需要相對較多的數學知識&#xff0c;對于前端開發者來說學習成本非常高。 Three.js是基于webGL的封裝的一個易于使用且輕量級的3D庫&#xff0c;T…

MySQL數據庫操作合集

一、SQL通用語法 ①SQL語句可以單行或多行書寫&#xff0c;以分號結尾。 ②SQL語句可以使用空格/縮進來增強語句可讀性。 ③MySQL數據庫的SQL語句不區分大小寫&#xff0c;關鍵字建議使用大寫。 ④注釋&#xff1a; 單行注釋&#xff1a; -- 注釋內容 或 # 注釋內容&#…

傳統工程項目管理與業財一體化管理的區別?

在工程項目管理領域&#xff0c;傳統管理模式與新興的業財一體化管理模式正在形成鮮明對比。隨著數字化轉型的加速&#xff0c;工程行業對高效、透明、協同的管理需求日益迫切。傳統工程項目管理依賴人工操作、分散系統和分模塊管理&#xff0c;難以應對復雜項目的全生命周期需…

敦煌網測評從環境搭建到風控應對,精細化運營打造安全測評體系

自養號測評&#xff0c;搶占流量為快速提升產品權重和銷量&#xff0c;很多賣家常采用自己養號補單測評的方式&#xff0c;技術搭建需要很多要素 一、硬件參數的關聯性 在我們使用設備進行注冊或操作賬號的過程中&#xff0c;系統會記錄下大量的系統與網絡參數&#xff0c;其中…

redis Pub/Sub 簡介 -16 (PUBLISH、SUBSCRIBE、PSUBSCRIBE)

Redis Pub/Sub 簡介&#xff1a;PUBLISH、SUBSCRIBE、PSUBSCRIBE Redis Pub/Sub 是一種強大的消息傳遞范例&#xff0c;可在應用程序的不同部分之間實現實時通信。它是構建可擴展和響應式系統的基石&#xff0c;允許組件在沒有直接依賴的情況下進行交互。本章將全面介紹 Redis…

JavaSE核心知識點03高級特性03-01(集合框架)

&#x1f91f;致敬讀者 &#x1f7e9;感謝閱讀&#x1f7e6;笑口常開&#x1f7ea;生日快樂?早點睡覺 &#x1f4d8;博主相關 &#x1f7e7;博主信息&#x1f7e8;博客首頁&#x1f7eb;專欄推薦&#x1f7e5;活動信息 文章目錄 JavaSE核心知識點03高級特性03-01&#xff0…