雙鏈樹是鍵樹(Trie 樹)的「孩子-兄弟」鏈式存儲實現,專為多路查找、字串集合索引設計。本文基於嚴蔚敏/吳偉民版《資料結構》第 9 章源碼,解析結構定義、插入刪除邏輯與查找流程。
// DLTree.h
typedef struct DLNode {
char ch; // 字元
struct DLNode *firstchild; // 長子指針 (下一層字元)
struct DLNode *nextsibling; // 兄弟指針 (同層下一字元)
bool isEnd; // 是否構成完整鍵值
void *data; // 關聯記錄指針
} DLNode, *DLTree;
Status InsertDLTree(DLTree *T, char *key, void *data) {
if (!*T) *T = CreateRoot();
DLNode *p = *T;
for (int i = 0; key[i]; ++i) {
DLNode *child = FindChild(p, key[i]);
if (!child) {
child = CreateNode(key[i]);
child->nextsibling = p->firstchild;
p->firstchild = child;
}
p = child;
}
if (!p->isEnd) {
p->isEnd = true;
p->data = data;
return OK;
}
return DUPLICATE; // 鍵已存在
}
void* SearchDLTree(DLTree T, char *key) {
DLNode *p = T;
for (int i = 0; key[i] && p; ++i) {
p = FindChild(p, key[i]);
}
return (p && p->isEnd) ? p->data : NULL;
}
Status DeleteDLTree(DLTree *T, char *key) {
// 1. 定位目標節點及其雙親
// 2. 標記 isEnd = false,釋放 data
// 3. 自底向上:若節點無子女且非終端,從雙親子鏈中移除並釋放
// 4. 遞歸向上清理無用節點
}
測試數據(TestData_Table.txt):
apple application apply banana band cat ...
測試結果:
| 維度 | 雙鏈樹 (孩子-兄弟) | 陣列式 Trie |
|---|---|---|
| 空間 | O(總字元數),極省記憶體 | O(節點數 × 字母表大小),浪費大 |
| 查找速度 | O(L × 平均兄弟數) | O(L),常數極小 |
| 實現複雜度 | 指針操作較繁瑣 | 陣列索引直觀簡單 |
| 適用場景 | 大字母表、稀疏鍵集、記憶體受限 | 小字母表(如 a-z)、高頻查找、記憶體充裕 |
雙鏈樹以「指針換空間、時間換空間」的經典權衡,在記憶體受限、字母表大、鍵集合稀疏的場景下展現獨特優勢。理解其孩子-兄弟轉換邏輯,也是掌握樹形結構通用表示法的關鍵一環。