本文提供一個 **純 C 語言** 實作的紅黑樹,包含插入、刪除、查找、中序列印、驗證等功能,並內建 **自動化壓力測試主程式**:隨機插入/刪除 10,000 節點,持續驗證樹性質 (BST 有序性、紅黑規則、黑高一致),確保刪除邏輯正確無誤。
#pragma pack(1)
typedef enum _color { RED, BLACK } color;
typedef struct _redblack {
color m_color;
int m_data; // 鍵值
struct _redblack *parent;
struct _redblack *left;
struct _redblack *right;
} redblack;
// 記憶體池包裝 (避免頻繁 malloc/free 影響測試效能)
typedef struct _wrapredblack {
struct _wrapredblack *next;
redblack real;
} wrapredblack;
typedef struct _wrapdata {
redblack *root;
int size;
} wrapdata;
#pragma pack()
| 函數 | 功能 |
|---|---|
rotate_left / rotate_right | 左/右旋,維護父指標與祖父連結 |
insert_fixup | 插入後修復紅黑性質 (Case 1~4) |
delete_fixup | 刪除後修復紅黑性質 (最複雜,處理雙黑、兄弟紅/黑、姪子紅/黑等 Case) |
find | 標準 BST 查找 |
next | 尋找後繼節點 (右子樹最左) |
check | 驗證 BST 有序性、父指標正確性 |
mid_print | 中序遍歷列印 (含位址、顏色、層級、值) |
int main() {
init_memory_pool(); // 初始化節點池
wrapdata *tree = calloc(1, sizeof(wrapdata));
srand(time(NULL));
while (1) {
// 隨機插入直到節點數達 COUNT (10000)
while (tree->size < COUNT) {
insert(tree, rand() % RAND);
validate(tree); // 每步驗證
}
// 隨機刪除直到節點數降至 COUNT/2
while (tree->size > COUNT/2) {
delete(tree, rand() % RAND);
validate(tree);
}
}
return 0;
}
int validate(wrapdata *tree) {
if (check(tree->root)) { mid_print(tree->root, 0); return 1; } // BST 性質違反
if (mid_print(tree->root, 0) != tree->size) return 1; // 節點數不符
if (error_label) return 1; // 遞迴過深
return 0;
}
delete_fixup 完整處理所有紅黑違規 Case。2*RAND 節點,mycalloc/myfree 從池取/還,提升測試速度並便於檢測 use-after-free。gcc -o rbtree_test rbtree.c
./rbtree_test
# 程式會持續運行並輸出中間樹狀 (size=6666 時),直到發現錯誤或手動停止