实现哈希表的方法有两种方法:开放寻址法 、链地址法
-
开放寻址法:在开放寻址法中,所有的元素都存储在哈希表的数组中,冲突发生时会探测下一个可用的位置,直到找到一个空闲的位置。这种方法保持了元素的顺序,但可能导致聚集(clustering)。
-
链地址法:链地址法使用一个数组来存储指向链表头部的指针,每个链表存储具有相同哈希值的元素。如果发生冲突,新的元素将被添加到该链表的末尾。这种方法可以避免聚集,但不保持元素的顺序。
链地址法:
#include <stdio.h>
#include <stdlib.h>#define SIZE 20
typedef struct Node {int value;int key;struct Node* next;
}Node;typedef struct{Node *table[SIZE];
}HashTable; //初始化哈希表
void initHashTable(HashTable *ht){for (int i = 0; i < SIZE; i++) {ht->table[i] = NULL;}
} int getKey(int value){return value%SIZE;
}//向哈希表中插入数据 hash公式就是 value%20
void addvalue(int value,HashTable *ht){Node *node=(Node*)malloc(sizeof(Node));node->value=value;int key=getKey(value);node->key=key;node->next=NULL;Node *tmp=ht->table[key];if(tmp!=NULL){while(tmp->next){tmp=tmp->next; }tmp->next=node;}else{ht->table[key]=node; }
}//查看哈希表中是否包含此值
int containValue(int value,HashTable *ht){int key=getKey(value);if(key<0){printf("查询非法数据!");return -1;}Node* tmp=ht->table[key];if(tmp==NULL) return 0;while(tmp){if(tmp->value==value) return 1;tmp=tmp->next;}return 0;
}// 释放哈希表内存
void freeHashTable(HashTable *ht) {for (int i = 0; i < SIZE; i++) {Node *current = ht->table[i];while (current != NULL) {Node *temp = current;current = current->next;free(temp);}}
}int main(){HashTable table;initHashTable(&table);addvalue(1,&table);addvalue(3,&table);addvalue(6,&table);addvalue(7,&table);addvalue(11,&table);addvalue(23,&table);addvalue(21,&table);addvalue(27,&table);addvalue(87,&table);printf("%d\n",containValue(-1,&table));freeHashTable(&table);system("pause");return 0;
}
开放寻址法
#include <stdio.h>
#include <stdlib.h>#define SIZE 100typedef struct Node {int value;int key;struct Node* next;
}Node;typedef struct {Node* node[SIZE];int magnification;
}HashTable;void initHashTable(HashTable *ht){int i;for(i=0;i<SIZE;i++){ht->node[i]=NULL;}ht->magnification=1;
}//获取索引,-2:该元素已经无法插入,-1:非法值
int getKey(int value,HashTable *ht){int key=value%SIZE;if(key>=0&&ht->node[key]!=NULL){int i;for(i=key+1;i<SIZE;i++){if(ht->node[i]==NULL) return i;}return -2;}else if(ht->node[key]==NULL){return key;}return -1;
}void pushToHt(int value,HashTable *ht){int key=getKey(value,ht);if(key==-1){printf("非法值的查找!\n");}else if(key==-2){printf("%d插入失败!\n",value);}else{Node *node=(Node*)malloc(sizeof(Node));node->key=key;node->value=value;node->next=NULL;ht->node[key]=node;}
}int containValue(int value,HashTable *ht){int key=value%SIZE;if(key==-1){printf("查询非法数据!\n");return -1;}else{return ht->node[key]!=NULL&&ht->node[key]->value==value?1:0;}
}int main(){HashTable ht;initHashTable(&ht);pushToHt(1,&ht);pushToHt(2,&ht);pushToHt(23,&ht);pushToHt(11,&ht);pushToHt(12,&ht);pushToHt(14,&ht);pushToHt(5,&ht);pushToHt(15,&ht);pushToHt(31,&ht);printf("%d\n",containValue(14,&ht));system("pause");return 0;
}