哈希链表的实现

本文介绍了哈希表的概念和企业级应用,通过一个真人CS活动的故事引入,阐述了哈希表在快速存取数据方面的优势。文章详细展示了哈希表的结构,包括键、值、索引、哈希桶和哈希函数,并提供了C++实现哈希表的代码示例,包括插入、查找和删除操作。此外,还涉及到了哈希表的初始化、销毁以及元素的检索。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

哈希表及其企业级应用 第 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;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值