首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

雙向鏈表 C++ 完整實現:從設計到測試的標準庫級教程

     編輯:關於C++

數據結構設計

雙向鏈表節點含 `data`、`prev`、`next` 三域。頭尾指針 `head`/`tail`,尺寸 `listSize`。哨兵節點可簡化邊界,但本實現採用裸指針 + 空檢查,教學意義更強。

核心接口設計

  • 修改操作:`push_front/back`, `pop_front/back`, `insert(pos, val)`, `erase(pos)`, `erase(range)`, `resize(n)`, `clear()`, `swap()`
  • 高級操作:`splice(pos, li1, li2)` 切分,`merge(li1, li2)` 合併,`remove(val)`, `remove_if(pred)`, `unique()`, `sort()`, `reverse()`
  • 查詢操作:`empty()`, `size()`, `front()`, `back()`, `operator[]`, `display()`
  • 賦值操作:`operator=`, `assign(li)`, `assign(arr, arr+n)`

關鍵實現細節

節點定位 `at(pos)`

從 `head` 向後遍歷 `pos` 步,O(pos) 時間。可優化:若 `pos > size/2` 從 `tail` 向前遍歷。

插入 `insert(pos, val)`

三種情況:頭插(`pos==0`)、尾插(`pos==size`)、中間插。統一邏輯:創建新節點,調整四個指針(新節點的 prev/next,鄰居節點的 next/prev),更新 `head`/`tail`/`size`。頭尾插復用中間邏輯可減少代碼但需處理空表情況。

刪除 `erase(pos)` / `erase(start, end)`

單點刪除:調整鄰居指針跳過被刪節點,`delete` 釋放內存,更新 `head`/`tail`/`size`。區間刪除:若涉及頭/尾批量調用 `pop_front/back`;中間區間直接重鏈接 `p1->prev->next = p2; p2->prev = p1->prev;` 然後遍歷刪除節點。

高級算法

  • `sort()`:簡易冒泡/選擇排序 O(n²),教學足夠。生產環境應用歸併排序 O(n log n)(鏈表適合歸併)。
  • `unique()`:雙重循環 O(n²) 去重,利用 `erase` 邏輯。
  • `reverse()`:雙指針頭尾交換 `data`,O(n) 時間 O(1) 空間,不動指針結構。
  • `splice()`:切分邏輯需仔細處理邊界,代碼中用 `push_back`/`push_front` 重建新表,簡單但非 O(1)。

模板與內存管理

模板參數 `typename DataType` 支持任意類型。構造/拷貝/析構函數遵循法則三:深拷貝、`assign` 復用、`clear` 遞歸 `pop_front` 釋放所有節點。無移動語義(C++11 前風格)。

測試驗證

測試代碼覆蓋 `int` 和 `string` 類型,驗證所有接口:構造、拷貝、合併、切分、刪除、去重、排序、反轉、擴容、下標訪問、首尾訪問。輸出示例展示各操作後狀態,邏輯正確。

優化建議

  • 引入哨兵節點統一頭尾邊界處理。
  • `sort()` 改用歸併排序。
  • `at(pos)` 雙向遍歷優化。
  • 添加迭代器支持(`begin()`, `end()`, `iterator` 類),兼容 STL 算法。
  • C++11 添加移動構造/賦值、`emplace` 系列、`noexcept` 標註。

總結

本實現代碼結構清晰、接口豐富、邏輯完整,是學習雙向鏈表、模板編程、內存管理的優秀教材。對比 `std::list` 可深入理解標準庫設計權衡。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved