哈希表实现

链表指针数组实现哈希表

哈希表,又称散列表,目的是实现更快的搜索,其利用数组的特性,理想情况下(无冲突,事实上也不可能)可以实现O(1)的时间复杂度.
本文给出用数组来存链表的方式来避免有限集描述更大集的冲突问题。

哈希表数据结构实现

  1. 结构体定义
typedef struct Node{
   
	int data;
	struct Node* next;
}ListNode;

struct HashTable{
   
	ListNode* elem[SIZE];
	int count;
}ht;

定义两个结构体,一个为存放链表头指针的数组(初始为空指针),
以及存放在哈希表中的数据数量count。

  1. 哈希函数实现
#define SIZE 20
#define NODESIZE 200

我们定义链表个数(数组长度)为20,那么如果用整除来实现哈希函数(值到地址(数组下标)的映射关系)
可以另哈希函数为以下:

int CalHash(int key){
   
	return key%(SIZE-1; //宏定义SIZE为20
}

这样相应可以使数据在哈希表中分布更加均匀,提高查找效率(书上是这么说的)。

3.哈希表初始化
因为数组中每一个节点都存放了一个地址,我们将每个数组元素都初始化为NULL指针,以便插入元素时,这个指针来接收malloc函数返回的地址。

void InitializeHash(){
   
	ht.count=0;
	for(int i=0;i<SIZE;i++)
		ht.elem[i]=NULL;	
}

哈希表搜索

函数原型

int SearchHash(int key,int* s)

搜索函数嵌套在插入函数和删除函数里面,在函数之间传递CalHash函数计算得到的数组下标,故此函数要传递两个参数,一个是要查找的关键字,另一个是CalHash返回的数组下标,用一个int* 传递。
详细代码

int SearchHash(int key,int* s){
   
	//(*s)=CalHash(key);
	ListNode* current=ht.elem[*s];
	while(current!=NULL){
   
		if(current->data==key)
			return 1;
		current=current->next;
	}
	return 0;
}

哈希表插入

函数原型

int InsertHash(int e)

形参e为插入的元素值。
详细代码

int InsertHash(int e){
   
	int s;
	if(ht.count==NODESIZE){
   
		printf("哈希表已满\n");
		return 1;
	}
	else{
   
		s=CalHash(e);
		int r=SearchHash(e,&s);
		if(r){
   
			printf("所处链表有重复元素,无法插入\n");
			return 0;
		}
		else{
   
			if(ht.elem[s]==NULL){
   		//空链表
				(ht
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、 设计课题:哈设计 二、 需求分析: 课题的目的和任务:根据数据元素的关键字和哈函数建立哈并初始化哈,用开放定址法处理冲突,按屏幕输出的功能选择所需的功能实现用哈对数据元素的插入,显示,查找,删除。 初始化哈时把elem[MAXSIZE]、elemflag[MAXSIZE]和count分别置0。创建哈时按哈函数创建哈,输入数据元素的关键字时,以“0”结束输入且要求关键字为正整数,数据元素个数不允许超过长MAXSIZE。 输出的形式:根据所选择的哈的功能输出相应提示语句和正确结果。 程序的功能:将一组个数不超过哈长度的数据元素,按其关键字和哈函数存入哈中,如果产生冲突用开放定址法处理并找出相应的地址。能实现用哈对数据元素的插入,显示,查找,删除。 测试数据: maxsize=10 哈函数:H(key)=key%7 处理冲突方法: 开放定址法 Hi=(H(key)+di)%13 i=1,2,3,…,9 三、实验概要设计: ADT HashTable { 数据对象:D1={ai|ai∈elem[MAXSIZE],i=0,1,2,…,0≦n≦MAXSIZE } elem [MAXSIZE]是哈中关键字的集合,MAXSIZE为哈长。} D2={ai|ai∈elemflag[MAXSIZE]是哈中有无关键字的标志的集合,MAXSIZE为哈长。} 基本操作: Hash(key) 初始条件:数据元素关键字key已存在 操作结果:根据哈函数计算相应地址,并返回此地址。 InitialHash(HashTable &H) 初始条件:哈H已存在 操作结果:初始化哈把elem[MAXSIZE]、elemflag[MAXSIZE]和count分别置0。 SearchHash(HashTable &H,int k) 初始条件:哈H已存在 操作结果:在开放定址哈H中查找关键字为k的元素,若查找成功,并返回SUCCESS;否则返回UNSUCCESS。 InsertHash(HashTable &H,int e) 初始条件:哈H已存在 操作结果:查找不成功时插入数据元素e到开放定址哈H中,并返回SUCCESS;否则输出已有此数!插入失败!并返回UNSUCCESS。 CreateHash(HashTable &H) 操作结果:构造哈。 PrintHash(HashTable H) 初始条件:哈H已存在 操作结果:将哈存储状态显示输出。 DeleteHash(HashTable &H,int e) 初始条件:哈H已存在 操作结果:若通过哈函数找到相应的位置并且此位置的elemflag[MAXSIZE]==1,删除相应位置的数据元素的关键字并把elemflag[MAXSIZE]==2,否则,输出无此数的提示语。 2. 本程序包括如下功能模块 哈函数模块,冲突处理模块,哈初始化模块,哈创建模块,哈显示模块,按关键字查找模块,插入模块,删除模块和主程序模块。 四、基本操作的算法描述: 1.宏定义 #define MAXSIZE 10 #define SUCCESS 1 #define UNSUCCESS 0 2.数据类型、数据元素的定义 typedef struct { int elem[MAXSIZE]; int elemflag[MAXSIZE]; int count; }HashTable; 3. 哈的基本操作的算法描述 //初始化哈函数 void InitialHash(HashTable &H)/*哈初始化*/ { int i; H.count=0; for(i=0;i<MAXSIZE;i++) { H.elem[i]=0; H.elemflag[i]=0; } } //哈函数 int Hash(int kn) /*哈函数H(key)=key MOD 7*/ { return (kn%7); } //查找函数 int SearchHash(HashTable &H,int k) /*查找关键字为k的元素*/ { int t,s; s=t=Hash(k); //调用哈函数 xun: if(H.elem[t]==k&&H.elemflag[t]==1) return SUCCESS; //如果相应的地址上的数等于k,返回1 else if(H.elem[t]!=k&&H.elemflag[t]==1) { //相应地址有数但不等于k并且H.elemflag[t]==1 t=(t+1)%MAXSIZE; // 处理冲突 goto xun; } else return UNSUCCESS; //返回0 } //插入函数 int InsertHash(HashTable &H,int e)/*插入元素e*/ { int p; p=Hash(e); if(SearchHash(H,e) ) //调用查找函数,如果有此数返回1 { cout<<"已有此数!"<<endl; return UNSUCCESS; //插入是吧,返回0 } else //查找失败,返回0 { H.elemflag[p]=1; //把状态标志置1 H.elem[p]=e; //把关键字放入相应的地址 H.count++; //计数加1 return SUCCESS; //插入成功,返回1 } } //创建哈的函数 void CreateHash(HashTable &H)/*创建哈*/ { int s; int e; cout<<"请输入哈:(输入0结束!)"<<endl; cin>>e; while(e) { s=InsertHash(H,e); //调用插入函数 if(!s) { cout<<"此数已存在!"; cin>>e; } else cin>>e; } } //显示函数 void PrintHash(HashTable H) /*显示元素及其位置*/ { cout<<"哈地址:"; int i; for(i=0;i<MAXSIZE;i++) cout<<i<<" "; cout<<endl<<"关键字: "; for(i=0;i<MAXSIZE;i++) cout<<H.elem[i]<<" "; cout<<endl<<"关键字标志:"; for(i=0;i<MAXSIZE;i++) cout<<H.elemflag[i]<<" "; } //删除函数 int DeleteHash(HashTable &H,int e) /*删除元素e*/ { int i; int a=0; for(i=0;i<MAXSIZE;i++) if(H.elem[i]==e&&H.elemflag[i]==1) { H.elemflag[i]=2; H.count--; H.elem[i]=0; a++; return SUCCESS; } if(!a) { cout<<"无此数!"<<endl; return UNSUCCESS; } } //主函数 void main() { HashTable H; int m,k,p; int R; do{ cout<<endl<<"\t\t******************请选择功能********************"<<endl; cout<<"\t\t\t1.初始化哈"<<endl<<"\t\t\t2.创建哈"<<endl<<"\t\t\t3.查找" <<endl<<"\t\t\t4.插入"<<endl<<"\t\t\t5.删除"<<endl<<"\t\t\t6.输出哈:"<<endl<<"\t\t\t0.退出"<<endl; cout<<"\t\t************************************************"<<endl; cin>>m; switch(m) { case 1: InitialHash(H);break; case 2: CreateHash(H);break; case 3: cout<<endl<<"请输入要查找的关键字:"; cin>>k; p=SearchHash(H,k); if(p) cout<<"查找成功!"<<endl; else cout<<"查找失败!"<<endl; break; case 4: cout<<endl<<"请输入要插入的关键字:"; cin>>R; p=InsertHash(H,R); if(p) cout<<"插入成功!"<<endl; else cout<<"插入失败!"<<endl; break; case 5: cout<<"请输出要删除的关键字:"; cin>>R; p=DeleteHash(H,R); if(p) cout<<"删除成功!"<<endl; else cout<<"删除失败!"<<endl; break; case 6: PrintHash(H);break; case 0: break; default: cout<<endl<<"选择错误!";break; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值