雜湊表之鏈地址發
阿新 • • 發佈:2018-11-11
鏈地址發
將所有的關鍵字為同義詞的記錄儲存在同一線性連結串列中。
比如,我們對於關鍵字集合{12,67,56,16,25,37, 22,29,15,47,48,34},我們用前面同樣的12為除數,進行除留餘數法:
當雜湊表中的元素個數等於雜湊表的容量時,雜湊表需要增容。
sum.h
typedef struct linklist { int data; struct linklist* next; }NODE; typedef struct hash { NODE* node; int capacity; int size; }Hash; void inithash(Hash* hash,int capacity);//初始化 int hashfunction(Hash* hash,int data);//雜湊函式 void inserthash(Hash* hash, int data);//入表 void removehash(Hash* hash, int data);//出表 int findhash(Hash* hash, int data);//尋找元素 void capacityadd(Hash* hash);//增容 int emptyhash(Hash* hash);//表空? int sizehash(Hash* hash);//表中的容量 void destroyhash(Hash* hash);//銷燬 void printfhash(Hash* hash);//列印 int getnextprime(int a);/獲取下一個質數
sum.c
#include"sum.h" #include<assert.h> #include<windows.h> #include<stdio.h> void inithash(Hash* hash,int capacity) { assert(hash); int i = 0; hash->node = malloc(sizeof(NODE)*capacity); for (i = 0; i < capacity; i++) { hash->node[i].next = NULL; } hash->capacity = capacity; hash->size = 0; } int hashfunction(Hash* hash,int data) { return data%hash->capacity; } NODE* buynode(int data) { NODE* pnew = malloc(sizeof(NODE)); pnew->next = NULL; pnew->data = data; return pnew; } void capacityadd(Hash* hash) { if (hash->capacity == hash->size) { int i = 0; int newcapacity = getnextprime(hash->capacity); NODE* pnew = malloc(sizeof(NODE)*newcapacity); for (i = 0; i < newcapacity; i++) pnew[i].next = NULL; hash->capacity = newcapacity; //拷貝 for (i = 0; i < hash->size; i++) { NODE* cur = hash->node[i].next; while (cur) { int newhashaddr = hashfunction(hash, cur->data); NODE* pnewnode = buynode(cur->data); NODE* cur1 = pnew[newhashaddr].next; if (pnew[newhashaddr].next == NULL)//插入的節點是雜湊表某個節點的第一個節點 { pnew[newhashaddr].next = pnewnode; } pnewnode->next = cur1; pnew[newhashaddr].next = pnewnode;//頭插 cur = cur->next; } } free(hash->node);//釋放原來的節點 hash->node = pnew; } } void inserthash(Hash* hash, int data) { assert(hash); capacityadd(hash);//增容 int hashaddr = hashfunction(hash, data); NODE* cur = NULL; NODE* pnew = buynode(data); cur = hash->node[hashaddr].next; if (hash->node[hashaddr].next == NULL)//插入的節點是雜湊表某個節點的第一個節點 { hash->node[hashaddr].next = pnew; hash->size++; return; } pnew->next = cur; hash->node[hashaddr].next = pnew; hash->size++; } void removehash(Hash* hash, int data) { assert(hash); int hashaddr = hashfunction(hash, data); NODE* cur = hash->node[hashaddr].next; NODE* parent = NULL; while (cur) { if (cur->data == data) { if (parent == NULL) { hash->node[hashaddr].next = cur->next; hash->size--; free(cur); cur = NULL; return; } parent->next = cur->next; hash->size--; free(cur); cur = NULL; return; } parent = cur; cur = cur->next; } printf("刪除的數不存在\n"); } int findhash(Hash* hash, int data) { assert(hash); int hashaddr = hashfunction(hash, data); NODE* cur = hash->node[hashaddr].next; NODE* parent = NULL; while (cur) { if (cur->data == data) { return 1; } parent = cur; cur = cur->next; } printf("尋找的數不存在\n"); return 0; } int emptyhash(Hash* hash) { assert(hash); int i ,count= 0; for (i = 0; i < hash->capacity; i++) { if (hash->node[i].next == NULL) count++; } if (count == hash->capacity) return 1; return 0; } int sizehash(Hash* hash) { return hash->size; } void destroyhash(Hash* hash) { assert(hash); int i; NODE* cur = NULL; for (i = 0; i < hash->capacity; i++) { cur = hash->node[i].next; while (cur != NULL) { NODE* del = cur; cur = del->next; free(del); del = NULL; } } } void printfhash(Hash* hash) { assert(hash); int i = 0; for (; i < hash->capacity; i++) { NODE* cur = hash->node[i].next; printf("node[%d]=", i); while (cur) { printf("%d--->", cur->data); cur = cur->next; } printf("NULL\n"); } } int getnextprime(int a) { int _PrimeSize = 28; int _PrimeList[28] = { 53ul, 97ul, 193ul, 389ul, 769ul, 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, 1610612741ul, 3221225473ul, 4294967291ul }; for (int i = 0; i < _PrimeSize; i++) { if (_PrimeList[i]>a) return _PrimeList[i]; } return _PrimeList[_PrimeSize - 1]; }
test.c
#include<windows.h> #include<stdio.h> #include"sum.h" int main() { Hash hash; inithash(&hash,12); inserthash(&hash, 12); inserthash(&hash, 67); inserthash(&hash, 56); inserthash(&hash, 16); inserthash(&hash, 25); inserthash(&hash, 37); inserthash(&hash, 22); inserthash(&hash, 29); inserthash(&hash, 15); inserthash(&hash, 47); inserthash(&hash, 48); inserthash(&hash, 34); printfhash(&hash); destroyhash(&hash); system("pause"); return 0; }
沒有在增容前的結果:
當我們繼續插入一個元素這時候雜湊表中的元素數大於雜湊表的容量時,我們就要對其增容: