雜湊表是介於鏈表與二叉樹之間的「黃金平衡點」:鏈表插刪 O(1) 但查詢 O(n);二叉樹查詢 O(log n) 但需額外指標與平衡維護。雜湊表以空間換時間,透過雜湊函數將鍵值映射到桶位,桶內以鏈表解決衝突,實現平均 O(1) 的查找、插入、刪除,且記憶體開銷可控。
typedef struct _NODE {
int data;
struct _NODE* next;
} NODE;
typedef struct _HASH_TABLE {
NODE* value[10]; // 固定 10 個桶位,簡化演示
} HASH_TABLE;
HASH_TABLE* create_hash_table() {
HASH_TABLE* pHashTbl = (HASH_TABLE*)malloc(sizeof(HASH_TABLE));
memset(pHashTbl, 0, sizeof(HASH_TABLE)); // 全桶位初始化為 NULL
return pHashTbl;
}
採用簡單取模法:index = data % 10
NODE* find_data_in_hash(HASH_TABLE* pHashTbl, int data) {
if (!pHashTbl) return NULL;
NODE* pNode = pHashTbl->value[data % 10];
if (!pNode) return NULL;
while (pNode) {
if (data == pNode->data) return pNode;
pNode = pNode->next;
}
return NULL;
}
STATUS insert_data_into_hash(HASH_TABLE* pHashTbl, int data) {
if (!pHashTbl) return FALSE;
int idx = data % 10;
if (!pHashTbl->value[idx]) { // 桶位為空,直接建立首節點
NODE* pNode = (NODE*)malloc(sizeof(NODE));
memset(pNode, 0, sizeof(NODE));
pNode->data = data;
pHashTbl->value[idx] = pNode;
return TRUE;
}
if (find_data_in_hash(pHashTbl, data)) return FALSE; // 去重
// 桶位非空,遍歷至鏈表尾部插入
NODE* pNode = pHashTbl->value[idx];
while (pNode->next) pNode = pNode->next;
pNode->next = (NODE*)malloc(sizeof(NODE));
memset(pNode->next, 0, sizeof(NODE));
pNode->next->data = data;
return TRUE;
}
STATUS delete_data_from_hash(HASH_TABLE* pHashTbl, int data) {
if (!pHashTbl || !pHashTbl->value[data % 10]) return FALSE;
NODE* pNode = find_data_in_hash(pHashTbl, data);
if (!pNode) return FALSE;
int idx = data % 10;
if (pNode == pHashTbl->value[idx]) { // 刪除桶位首節點
pHashTbl->value[idx] = pNode->next;
goto final;
}
// 刪除中間/尾部節點:需找前驅
NODE* pHead = pHashTbl->value[idx];
while (pNode != pHead->next) pHead = pHead->next;
pHead->next = pNode->next;
final:
free(pNode);
return TRUE;
}
| 操作 | 平均複雜度 | 最壞複雜度 | 備註 |
|---|---|---|---|
| 查找 | O(1) | O(n) | 退化為鏈表時 |
| 插入 | O(1) | O(n) | 含去重查找 |
| 刪除 | O(1) | O(n) | 含查找+前驅定位 |