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

雜湊二元樹:結合雜湊表與二元樹的高效查找混合結構

     編輯:關於C語言

背景:平衡二元樹的查找瓶頸

AVL、紅黑樹等平衡二元樹雖保證 O(log N) 查找,但頻繁插入/刪除導致旋轉調整,實際效能波動大。極端情況下(如單邊鏈狀退化),查找降為 O(N)。

/* 極端退化範例:查找 1 需遍歷 7 個節點 */
      7           3
     /             \
    6               4
   /                 \
  5                   7
 /                     \
2                       12
/                         \
1                           20

三大改良方向比較

方案核心思想查找複雜度維護成本
AVL 樹嚴格平衡(高度差 ≤1)O(log N)高(頻繁旋轉)
紅黑樹近似平衡(黑高一致)O(log N)中
雜湊二元樹雜湊表直接定位 + 樹維持順序O(1) 平均低(雜湊表增刪 O(1))

雜湊二元樹結構設計

節點新增 `next` 指標,串接同雜湊桶位的節點;外部維護一個雜湊表(指標陣列)。

typedef struct _HASH_TREE {
    int data;
    struct _HASH_TREE* next;  // 雜湊鏈表指標
    struct _HASH_TREE* left;  // 樹左子節點
    struct _HASH_TREE* right; // 樹右子節點
} HASH_TREE;

// 雜湊表:指標陣列,大小為質數
#define HASH_TABLE_SIZE 10007
HASH_TREE* g_hash_table[HASH_TABLE_SIZE] = {NULL};

unsigned int hash_func(int data) {
    return (unsigned int)data % HASH_TABLE_SIZE;
}

核心操作框架

插入:雙重維護

STATUS add_node_into_tree(HASH_TREE** ppHash, int data) {
    // 1. 樹中插入(標準 BST 邏輯,略)
    // insert_into_bst(ppHash, data);

    // 2. 雜湊表插入(頭插法)
    unsigned int idx = hash_func(data);
    HASH_TREE* pNode = find_in_bst(*ppHash, data); // 取得剛插入的節點指標
    if (pNode) {
        pNode->next = g_hash_table[idx];
        g_hash_table[idx] = pNode;
    }
    return TRUE;
}

刪除:雙重清理

STATUS delete_node_from_tree(HASH_TREE** ppHash, int data) {
    // 1. 從樹中刪除(標準 BST 刪除,取得被刪節點指標 pNode)
    HASH_TREE* pNode = find_in_bst(*ppHash, data);
    if (!pNode) return FALSE;

    // delete_from_bst(ppHash, data); // 樹結構調整

    // 2. 從雜湊表移除(單向鏈表刪除需記錄前驅)
    unsigned int idx = hash_func(data);
    HASH_TREE **pp = &g_hash_table[idx];
    while (*pp && *pp != pNode) pp = &(*pp)->next;
    if (*pp) *pp = pNode->next; // 旁路移除

    free(pNode);
    return TRUE;
}

查找:O(1) 直接命中

HASH_TREE* find_in_hash_tree(int data) {
    unsigned int idx = hash_func(data);
    HASH_TREE* p = g_hash_table[idx];
    while (p) {
        if (p->data == data) return p; // 精確匹配
        p = p->next;
    }
    return NULL;
}

關鍵設計考量

  1. 雜湊衝突處理:採用鏈表法(`next` 指標),負載因子過高時需 Rehash 擴容。
  2. 記憶體一致性:樹節點與雜湊表節點共用同一記憶體塊,`next` 僅作為雜湊鏈表連結,不干擾樹結構。
  3. 有序操作保留:範圍查詢、中序遍歷、前驅/後繼仍走樹結構(`left`/`right`)。
  4. 執行緒安全:多執行緒環境需對雜湊表桶位加鎖或採用無鎖結構。

適用場景

  • 高頻點查找、低頻範圍查詢的業務(如用戶 ID 索引、快取索引)。
  • 記憶體資料庫二級索引實作。
  • 需同時支援 `GET(key)` 和 `SCAN(range)` 的系統。

總結

雜湊二元樹以空間換時間(額外雜湊表 + `next` 指標),將點查找從 O(log N) 降為 O(1),同時保留樹的有序特性。是工程中平衡效能與功能的經典混合結構模式。

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