哈希表及其企业级应用 第 1 节 哈希表的故事导入 故事情节 为了提高开发团队精神,缓解工作压力,某 IT 公司组织开发团队的 12 位男同事和测试团队 的 12 位女同事开展真人 CS 4vs4 野战联谊!面对性感的女同事,男同事们个个摩拳擦掌,跃跃欲 试!野战活动那天,根据男女搭配,干活不累的原则,带队的专业教练让男同事站成一排,女同 事站成一排,然后要求从女生这排开始从 1 开始报数,每个报数的队员都要记住自己的编号: 1, 2, 3,4。。。。。。林子里响起了百灵鸟般的报数声
哈希表 - 散列表,它是基于快速存取的角度设计的,也是一种典型的“空间换时间”的做法 键(key): 组员的编号 如, 1 、 5 、 19 。 。 。 值(value): 组员的其它信息(包含 性别、年龄和战斗力等) 索引: 数组的下标(0,1,2,3,4) ,用以快速定位和检索数据 哈希桶: 保存索引的数组(链表或数组),数组成员为每一个索引值相同的多个元素 哈希函数: 将组员编号映射到索引上,采用求余法 ,如: 组员编号 19
#include<stdio.h>
#include<Windows.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
#define TABLESIZE 16
typedef struct _NodeList{
int key;//建值
void *date;
_NodeList *next;
}ListNode,NodeList;
typedef ListNode* List;
typedef NodeList* elem;
typedef struct _HashTable{
int tableSize;
List *thelist;
}HashTable;
//哈希函数
int Hash(int tablesize,int key){
return (key%tablesize);
}
//初始化哈希链表
HashTable *initHash(HashTable *Hash,int tablesize){
//初始化哈希桶
Hash = (HashTable*)malloc(sizeof(HashTable));
if(!Hash){
printf("error!\n");
return NULL;
}
//给索引指针分配内存
if(tablesize<0){
tablesize = TABLESIZE;
}
Hash->tableSize = tablesize;
Hash->thelist = (List*)malloc(sizeof(List)*tablesize);
if(!Hash->thelist){
printf("error malloc!\n");
free(Hash);
//return ;
}
for(int i=0;i<tablesize;i++){
//给每个哈希数组指针分配头节点的堆内存
Hash->thelist[i] = (ListNode*)malloc(sizeof(ListNode));
if(!Hash->thelist[i]){
//释放内存
printf("error malloc!\n");
free(Hash->thelist);
free(Hash);
}else{
memset(Hash->thelist[i],0,sizeof(NodeList));
}
}
return Hash;
}
//通过key查找元素
elem find(HashTable *&H,int key){
if(!H) return NULL;
//找到索引下标
int i =0;
i= Hash(H->tableSize,key);
List e = H->thelist[i]->next;
while(e!=NULL&&e->key!=key){
e = e->next;
}
//要么成功找到key,要么key不存在
return e;
}
//插入元素
bool insertHash(HashTable *H,int key,void *value){
//
//if(!H) return false;
//通过键值找到元素
elem e = find(H,key);
elem tmp = NULL;
elem L = NULL;
//tmp可能存在也可能不存在,当e不存在时
//e不存在
if(!e){
// tmp = (elem)malloc(sizeof(elem));
tmp = (elem)malloc(sizeof(NodeList));
if(tmp==NULL){
printf("eroor malloc!\n");
return false;
}
L = H->thelist[Hash(H->tableSize,key)]; //通过key的索引找出相应的位置
tmp->date = value;
tmp->key = key;
tmp->next = L->next;
L->next = tmp;
}else{
printf("the key has been exit!\n");
}
}
//删除元素
bool deleteElem(HashTable *H,int key){
//
//找元素
elem last = NULL;
elem e = NULL;
//elem e = find(H,key);//找到相应的索引位?????我在干嘛
List L = H->thelist[Hash(H->tableSize,key)];
last = L;
e = L->next;
while(e!=NULL&&e->key!=key){
last = e;
e = e->next;
}
//如果找到了这个L
if(e){
//直接把它跳过
last->next = e->next;
delete(e);
return true;
}
return false;
}
void *Retrive(elem e){
//获取表中的元素
return e!=NULL?e->date:NULL;//e存在就返回他自己的值否则就返回为空
}
//销毁哈希表
void destoyedHash(HashTable *&H){
elem e = NULL;
elem L = NULL;
elem cur = NULL;
for(int i=0;i<H->tableSize;i++){
L = H->thelist[i];
cur = L->next;
while(cur!=NULL){
elem tmp = cur;
cur = tmp->next;
free(tmp);
//cur = cur->next;
}
free(L);
}
free(H->thelist);
free(H);
H = NULL;
}
int main(){
char *elems[]={"小花","小芳","苍老师"};
HashTable *Hash = NULL;
Hash =initHash(Hash,TABLESIZE);
if(insertHash(Hash,1,elems[0])){
printf("插入元素成功!\n");
}
if(insertHash(Hash,2,elems[1])){
printf("插入元素成功!\n");
}
if(insertHash(Hash,3,elems[2])){
printf("插入元素成功!\n");
}
deleteElem(Hash,1);
destoyedHash(Hash);
//查找元素
elem e;
for(int i=0;i<4;i++){
e = find(Hash,i);
if(e){
//cout<<"e->date"<<e->date<<endl;
printf("%s\n",e->date);
}
}
printf("%s\n",Retrive(e));
system("pause");
return 0;
}