【資料結構與演算法】【查詢】雜湊表的程式碼實現
阿新 • • 發佈:2019-01-29
// Filename: hash.c #include <stdio.h> #include <stdlib.h> #include "public.h" #include "hash.h" // 雜湊表初始化,雜湊表長度為size int InitHashTable(HashTable *pH, int size) { int i = 0; if ((!pH) || (size <= 0)) { return HASH_ERROR_INIT; } pH->pElem = malloc(sizeof(HElemType) * size); if (!pH->pElem) { return HASH_ERROR_MALLOC; } for (i = 0; i < size; i++) { pH->pElem[i] = HASH_ELEM_INVALID_VALUE; } pH->totalnum = size; pH->existnum = 0; return OK; } // 雜湊函式:計算雜湊地址 int Hash(int key) { return key % HASH_TABLE_SIZE; } // 查詢關鍵字,返回雜湊地址 int SearchHash(HashTable *pH, int key, int *pAddr) { if ((!pH) || (!pAddr)) return ERROR; // key值不能和Hash表元素的初始預設值相同,否則就會被後面的元素覆蓋 if (HASH_ELEM_INVALID_VALUE == key) return HASH_ERROR_KEY; // 進行查詢操作 *pAddr = Hash(key); while (pH->pElem[*pAddr] != key) { *pAddr = (*pAddr + 1) % HASH_TABLE_SIZE; if ((HASH_ELEM_INVALID_VALUE == pH->pElem[*pAddr]) || (*pAddr == Hash(key))) { return HASH_ERROR_NOT_FOUND; } } return OK; } // 插入元素,衝突處理方法:開放定址法線性探測 int InsertHash(HashTable *pH, int key) { int addr; if (!pH) return ERROR; // key值不能和Hash表元素的初始預設值相同,否則就會被後面的元素覆蓋 if (HASH_ELEM_INVALID_VALUE == key) return HASH_ERROR_KEY; // 表滿則無法插入,返回錯誤 if (pH->existnum >= pH->totalnum) return HASH_ERROR_FULL; // 已經插入的元素,不能重複插入 if (OK == SearchHash(pH, key, &addr)) { printf("該元素已經在雜湊表中,無需重複插入\n"); return OK; } // 進行插入操作 addr = Hash(key); while (HASH_ELEM_INVALID_VALUE != pH->pElem[addr]) { addr = (addr + 1) % HASH_TABLE_SIZE; } pH->pElem[addr] = key; pH->existnum++; return OK; } // 刪除關鍵字,有則刪除,沒有不做操作 int DeleteHash(HashTable *pH, int key) { int addr; if (!pH) return ERROR; // key值不能和Hash表元素的初始預設值相同,否則就會被後面的元素覆蓋 if (HASH_ELEM_INVALID_VALUE == key) return HASH_ERROR_KEY; if (OK == SearchHash(pH, key, &addr)) { if (pH->existnum <= 0) pH->existnum = 1; // 此處應提示異常,說明程式實現有問題; pH->pElem[addr] = HASH_ELEM_INVALID_VALUE; pH->existnum--; } //printf("DeleteHash(): 未找到待刪除元素%d.", key); return OK; } // 列印雜湊表 void PrintHash(HashTable *pH) { int i; if (!pH) return; printf("雜湊表: 空間大小: %d, 元素數量: %d.\n", pH->totalnum, pH->existnum); printf("-----------------------------------\n"); printf("下標 元素值\n"); printf("-----------------------------------\n"); for (i = 0; i < pH->totalnum; i++) { printf("%-8d%-6d\n", i, pH->pElem[i]); } printf("-----------------------------------\n"); return; } int hash_main() { int input; int addr; int key; int retCode; HashTable H; while (1) { printf("----------------------------------\n"); printf("雜湊表基本操作\n"); printf("----------------------------------\n"); printf("0.建立/初始化雜湊表\n"); printf("1.插入元素\n"); printf("2.刪除元素\n"); printf("3.查詢元素\n"); printf("4.列印雜湊表\n"); printf("9.退出系統\n"); printf("----------------------------------\n"); printf("請選擇:"); scanf("%d", &input); getchar(); switch (input) { case 0: retCode = InitHashTable(&H, HASH_TABLE_SIZE); if (OK == retCode) { printf("建立/初始化雜湊表成功!\n"); } else { printf("建立/初始化雜湊表失敗!!!\n"); } break; case 1: printf("請輸入待插入元素: --> "); scanf("%d", &key); retCode = InsertHash(&H, key); if (OK == retCode) { printf("插入元素成功!\n"); } else { printf("插入元素失敗!!!\n"); } break; case 2: printf("請輸入待刪除元素: --> "); scanf("%d", &key); retCode = DeleteHash(&H, key); if (OK == retCode) { printf("刪除元素成功!\n"); } else { printf("刪除元素失敗!!!\n"); } break; case 3: printf("請輸入待查詢元素: --> "); scanf("%d", &key); retCode = SearchHash(&H, key, &addr); if (OK == retCode) { printf("查詢元素成功, 所在位置為: %d.\n", addr); } else { printf("查詢元素失敗!!!\n"); } break; case 4: PrintHash(&H); break; case 9: printf("系統已退出!\n"); exit(0); default: printf("無效,請重新選擇操作!\n"); exit(0); } } return 0; }