數據結構設計
雙向鏈表節點含 `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` 可深入理解標準庫設計權衡。