数据结构:哈希表设计(c++)

一、实验题目

根据数据结构知识,设计哈希表的相关内容

二、需求分析

[问题描述]
针对某个集体中人名设计一个哈希表,使得平均查找长度不超过 R,并完成相应的建表
和查表程序。
[基本要求]
假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有 30 个,取平均查找
长度的上限为 2。哈希函数用除留余数法构造,用线性探测再散列法或链地址法处理冲突。
[测试数据]
取读者周围较熟悉的 30 个人名。
[选作内容]
(1)从教科书上介绍的集中哈希函数构造方法中选出适用者并设计几个不同的哈希函
数,比较他们的地址冲突率(可以用更大的名字集合作实验)。
(2)研究这 30 个人名的特点,努力找一个哈希函数,使得对于不同的拼音名一定不发
生地址冲突。
(3)在哈希函数确定的前提下尝试各种不同处理冲突的方法,考察平均查找长度的变
化和造好的哈希表中关键字的聚集性。

三、概要设计

代码如下

/*pmj 20191220*/
#include<iostream>
#include<malloc.h>
#include<string.h>
using namespace std;
#define geshu 50                       //哈希表的长度
#define M 50
#define NAME_NO 30
typedef struct {
char *name;
	int k;                                //拼音所对应的关键字
} Name;
typedef struct {
	char *name;
	int k;                                //拼音所对应的关键字
int len;                               //查找长度
} HASH;
Name ren[geshu];
HASH halt[geshu];
//main函数
int main() {
	char *z;
	int r, s0;
	float average = 0;
	for(int i=0; i<geshu; i++) {
		cin>>ren[i].name;
	}
	for (int i = 0; i < NAME_NO; i++) {               //求整数
	s0 = 0;
		z = ren[i].name;                       //方法:将字符串的各个字符所对应的ASCII码相加,所得的整数做为哈希表的关键字
		for (r = 0; *(z + r) != '\0'; r++)          //当字符为空时停止计算
			s0 = *(z + r) + s0;
		ren[i].k = s0;                         //利用循环将所有字符的ASCII码值相加
	}                                               //最终的到的值就是ASCII码值和
	for (int i = 0; i < geshu; i++) {               //哈希表的初始化
		halt[i].name = "";
		halt[i].k = 0;
		halt[i].len = 0;
	}
	for (int i = 0; i < NAME_NO; i++) {
		int sum = 0;
		int adr = (ren[i].k) % M;               //利用除留余数法构造哈希函数
		int d = adr;
		if (halt[adr].len == 0) {                 //如果不冲突则存储到哈希表中
			halt[adr].k = ren[i].k;
		halt[adr].name = ren[i].name;
		halt[adr].len = 1;
		} else {                                     //存在冲突
			do {
				d = (d + ((ren[i].k)) % 10 + 1) % M;
				sum = sum + 1;                       //查找次数加1
			} while (halt[d].k != 0);
			halt[d].k = ren[i].k;
			halt[d].name = ren[i].name;     //数值存入哈希表
			halt[d].len = sum + 1;                //接着查找下一个字符
		}
	}
	cout << "姓名为:" <<"\t" << "地址为:" << "\t" << "关键字为:" << "\t\t" << "搜索的长度为:" << "\t" << "H为:" << "\t\t"<< endl;  //显示的格式
	for (int i = 0; i < 50; i++) {
		cout << halt[i].name<< i << "\t" << halt[i].k << "\t\t" << halt[i].len << "\t\t" << (halt[i].k) % M << "\t\t"  << endl;
	}                                                 //依次输出
	for (int i = 0; i < geshu; i++)
		average += halt[i].len;                    //计算平均查找长度
	average /= NAME_NO;
	cout << "平均查找长度:ASL " << NAME_NO << "=" << average << endl;
}

四、调试分析

在这里插入图片描述
调试结果如图所示,无错误。

五、使用说明

第一步:在程序中输入30个人名
第二步:输出地址、关键字、探索长度、H、姓名

六、测试结果

在这里插入图片描述

七、其他数据结构实例

数据结构:编程带你了解约瑟夫环
数据结构:简易停车场管理系统
数据结构:哈夫曼编/译码设计
数据结构:图的基本操作模拟-校园导游

以上内容为个人学习总结,如有遗漏或者错误请在评论区中指正!!!

如果看完觉得有所收获的话,记得一键三连哦,谢谢大家!

  • 13
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
哈希表是一种常用的数据结构,用于存储和快速检索数据。在哈希表中,使用哈希函数来将数据的关键字映射到对应的索引位置。然而,由于数据的范围广、不集中以及不同关键字可能计算出相同的哈希地址,会导致哈希冲突的出现。 对于哈希冲突的处理,有多种方法可以选择。其中一种常见的方法是使用链地址法,即在哈希表的每个位置上使用一个链表来存储具有相同哈希地址的数据元素。当发生哈希冲突时,新的数据元素可以被插入到对应位置的链表中。 另一种方法是开放地址法,它尝试将数据插入到其他空闲的位置,直到找到一个空闲位置或者遍历完所有的位置。开放地址法有多种实现方式,例如线性探测、二次探测和双重哈希等。 还有一种方法是使用再哈希法,即使用不同的哈希函数来解决冲突。如果发生冲突,就使用另一个哈希函数重新计算哈希地址,直到找到一个空闲位置为止。 总之,哈希表是一种高效的数据结构,可以通过哈希函数将数据存储在数组中,但是在处理哈希冲突时需要选择合适的解决方法,如链地址法、开放地址法或再哈希法等。这样可以确保在插入和查找数据时都能保持较高的效率。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【 C++哈希表底层结构剖析](https://blog.csdn.net/bit_zyx/article/details/126864217)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值