1. 尋找的資料是表式結構,可以想象成是資料庫裡的表;
2. 尋找的目的是找出表中關鍵字與給定關鍵字相等的資料行;
3. 雜湊表就是定義了每一個資料行的行號;
4. 雜湊演算法就是 行號=f(關鍵字),所以在雜湊表裡尋找資料時,不需要把給定關鍵字與每一行的關鍵字比較是否相等來找到行號,而是直接由給定的關鍵字計算出行號;
5.不同的關鍵字可能對應相同的行號,這就是衝突,最先佔用此行號的資料就被放到該行,而後續和它衝突的資料則需要重新計算行號,直到找到一個尚未被佔用的行號;
反過來,在搜尋資料時,先計算出行號,但是這個行號裡存的資料不應就是要找的,需要比較此行資料的關鍵字與給定的關鍵字是否相同,如果不同則繼續計算下一個可能的行號,並繼續比較,直到相同為止。
hash表在初始化時,必須給定每一個一個行號是否已經被佔用的標誌;在搜尋時,必須判定搜的的行號對應的關鍵字是否確實與給定的關鍵字相等。
直接代碼:
#define HASHSIZE 12#define NULLKEY -32768#include <stdio.h>#include <stdlib.h>typedef struct{ int *elem; int count;}HashTable;int m = 0;/* 初始化列表*/int InitHashTable(HashTable* H){ int i; m = HASHSIZE; H->count = m; H->elem = (int*) malloc(m*sizeof(int)); for(i=0; i<m; i++) { H->elem[i] = NULLKEY; } return 0;}/* 散列函數 */int Hash(int key){ return key%m;}/* 填充雜湊表 */int InsertHash(HashTable *H, int key){ int addr = Hash(key); /*求散列位置 */ while(H->elem[addr] != NULLKEY) { addr = (addr+1) %m; printf("新地址:%d\n", addr); } H->elem[addr] = key; return addr;}/* 尋找Hash表 */int SearchHash(HashTable *H, int key, int *addr){ *addr = Hash(key); while(H->elem[*addr] != key) /*如果找到的地址裡存放的資料不是key */ { *addr = (*addr + 1) % m; if(H->elem[*addr] == NULLKEY || *addr == Hash(key)) /* 不存在這個關鍵字 */ { return -1; } } return 0;}
int main(int argc, char** argv){ HashTable H; InitHashTable(&H);
int keys[] = {48, 37, 15, 16, 29, 67, 56, 34, 47, 22, 12, 25 }; int i = 0; for(i = 0; i<(sizeof(keys)/sizeof(int)); i++) { int x = InsertHash(&H, keys[i]); printf("%d---%d\n", x, keys[i]); } int addr; int key; scanf("%d", &key); int r = SearchHash(&H, key, &addr); if(r==0) { printf("找到了! %d\n", addr); } else { printf("沒找到!\n"); } return 0;}