鏈式雜湊,一致性雜湊
阿新 • • 發佈:2021-06-29
雜湊
雜湊(Hash):雜湊函式 雜湊函式:我們可以非常大範圍的輸入通過雜湊函式變成一定大小的輸出 一定大小的輸出也叫雜湊值 儲存位置 = f(關鍵字) f() == 雜湊函式 雜湊演算法是一種廣義的思想,我們一般只要演算法採用了雜湊函式的思想,那這個演算法就可以叫雜湊演算法 之前學習的資料結構資料之間有關係嗎? 有 雜湊表中的資料有關係? 儲存地址只跟關鍵字key有關 儲存節點的方式以及查詢節點的方式與之前學習到的資料結構都不一致雜湊函式的構造方法:
1.直接定址法
優點:適合查詢表較小並且連續的情況2.數字分析法
優點:適合關鍵字位數比較大的情況下,如果事先知道關鍵字的分佈並且關鍵字的若干位分佈較均勻, 就可以考慮使用這個方法3.平方取中法
4.摺疊法
優點:適合事先不知道關鍵字的分佈,適合關鍵字位數較多的情況5.除留餘數法
此方法為最常用的雜湊構造方法,對於散列表長度為m,通常p為小於或者等於m的最小質數或者不包含小於20質因子的合數
6.隨機數法
適合於關鍵字的長度不等,採用這個隨機數法處理雜湊衝突的方法?
1.開放定址法
2.再雜湊函式法
3.鏈地址法
4.公共溢位區法
一致性雜湊:
我們申請一大堆虛擬節點,就可以降低出現大量資料聚集在同一個伺服器上的情況概率。
A` A``認為是A的分身
B` B``認為是B的分身
C` C``認為是C的分身
遇到分身,即可認為遇到本人
#include <stdio.h> #include <assert.h> #include <stdlib.h> #define HASHSIZE 12 typedef struct Node { union { int data; int length; }; struct Node *next; }Node, *PNode; typedef struct Head { struct Node arr[HASHSIZE];//struct Node* arr[HASHSIZE];}Head, *PHead; void Init_Hash(PHead ph) { //assert for(int i=0; i<HASHSIZE; i++) { ph->arr[i].next = NULL; } } bool Insert_Hash(PHead ph, int key) { //assert int hash = key % HASHSIZE; struct Node *pnewnode = (struct Node*)malloc(sizeof(struct Node)); if(pnewnode == NULL) { return false; } pnewnode->data = key; pnewnode->next = ph->arr[hash].next; ph->arr[hash].next = pnewnode; return true; } bool Del_Hash(PHead ph, int key) { //assert int hash = key % HASHSIZE; struct Node *p = &ph->arr[hash]; for(p; p->next!=NULL; p=p->next) { if(key == p->next->data) { struct Node *q = p->next; p->next = q->next; free(q); return true; } } return false; } struct Node* Search(PHead ph, int key) { //assert int hash = key % HASHSIZE; struct Node *p = ph->arr[hash].next; for(p; p!=NULL; p=p->next) { if(p->data == key) { return p; } } return NULL; } void Printf_Hash(PHead ph) { //assert for(int i=0; i<HASHSIZE; i++) { printf("%d: ", i); struct Node *p = ph->arr[i].next; for(p; p!=NULL; p=p->next) { printf("%d ", p->data); } printf("\n"); } } void Destroy(PHead ph) { //assert for(int i=0; i<HASHSIZE; i++) { struct Node *p = &ph->arr[i]; for(p; p->next!=NULL; p=p->next) { struct Node *q = p->next; p->next = q->next; free(q); } } } void Clear(PHead ph) { Destroy(ph); } int main() { Head ph; Init_Hash(&ph); Insert_Hash(&ph, 12); Insert_Hash(&ph, 25); Insert_Hash(&ph, 15); Insert_Hash(&ph, 16); Insert_Hash(&ph, 29); Insert_Hash(&ph, 67); Insert_Hash(&ph, 57); Insert_Hash(&ph, 22); Insert_Hash(&ph, 47); Insert_Hash(&ph, 37); Insert_Hash(&ph, 48); Insert_Hash(&ph, 34); Printf_Hash(&ph); printf("-------------->\n"); Del_Hash(&ph, 12); Printf_Hash(&ph); return 0; }