複雜鏈表節點包含三個指標:`_next`(下一節點)、`_random`(任意節點/NULL)。要求**深度複製**整個鏈表,新舊節點記憶體完全獨立,且 `_random` 指向對應的新節點。
typedef struct ComplexNode {
int _data;
struct ComplexNode *_next;
struct ComplexNode *_random;
} ComplexNode, *pComplexNode;
#include#include // 複製複雜鏈表 void CopyComplexList(pComplexNode head, pComplexNode *newHead) { if (!head) { *newHead = NULL; return; } // 步驟 1: 交織複製節點 pComplexNode cur = head; while (cur) { pComplexNode copy = malloc(sizeof(ComplexNode)); copy->_data = cur->_data; copy->_next = cur->_next; copy->_random = NULL; cur->_next = copy; cur = copy->_next; } // 步驟 2: 設定 random 指標 cur = head; while (cur) { pComplexNode copy = cur->_next; if (cur->_random) copy->_random = cur->_random->_next; // 關鍵! cur = copy->_next; } // 步驟 3: 拆分兩個鏈表 cur = head; *newHead = head->_next; while (cur) { pComplexNode copy = cur->_next; cur->_next = copy->_next; // 恢復原鏈表 if (copy->_next) copy->_next = copy->_next->_next; // 串聯新鏈表 cur = cur->_next; } } // 輔助:建立測試鏈表 pComplexNode build_test_list() { pComplexNode n1 = malloc(sizeof(ComplexNode)); n1->_data = 1; pComplexNode n2 = malloc(sizeof(ComplexNode)); n2->_data = 2; pComplexNode n3 = malloc(sizeof(ComplexNode)); n3->_data = 3; pComplexNode n4 = malloc(sizeof(ComplexNode)); n4->_data = 4; n1->_next = n2; n2->_next = n3; n3->_next = n4; n4->_next = NULL; n1->_random = n3; n2->_random = n4; n3->_random = n2; n4->_random = n1; return n1; } void print_list(pComplexNode head) { while (head) { printf("Node %d: random -> %s\n", head->_data, head->_random ? "Node %d" : "NULL", head->_random ? head->_random->_data : 0); head = head->_next; } } int main() { pComplexNode head = build_test_list(); pComplexNode newHead = NULL; CopyComplexList(head, &newHead); printf("Original:\n"); print_list(head); printf("Copy:\n"); print_list(newHead); // 驗證記憶體獨立性 return 0; }
步驟1 交織: 原: 1 -> 2 -> 3 -> 4 新: 1' -> 2' -> 3' -> 4' 合: 1 -> 1' -> 2 -> 2' -> 3 -> 3' -> 4 -> 4' 步驟2 設定 random: 原 1.random = 3 => 1'.random = 3->_next = 3' 原 2.random = 4 => 2'.random = 4->_next = 4' ... 步驟3 拆分: 原鏈表恢復: 1 -> 2 -> 3 -> 4 新鏈表形成: 1' -> 2' -> 3' -> 4'
| 方法 | 時間 | 空間 | 優點 | 缺點 |
|---|---|---|---|---|
| 三步法(本文) | O(n) | O(1) | 空間最優、無需雜湊表 | 修改原鏈表結構(需恢復) |
| 雜湊表法 | O(n) | O(n) | 直觀、不修改原表 | 額外 O(n) 空間 |
| 遞迴+備忘錄 | O(n) | O(n) | 函數式風格 | 堆疊溢位風險 |
複雜鏈表深度複製是經典面試硬題。**三步法(交織→設random→拆分)**以 O(1) 額外空間、O(n) 時間完美解決,展現了「利用原結構暫存資訊」的精妙思維。務必熟練手寫三個 while 迴圈,並能畫出記憶體圖解釋每一步指標變化。