数据结构实验五:查找与排序(一):哈希查找(针对某个集体(比如你所在的班级)中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序)

本文介绍如何使用哈希查找技术设计一个哈希表,以存储班级人名,确保平均查找长度不超过15。通过除留余数法构建哈希函数,采用链式结构处理冲突。实验涉及哈希表创建、冲突解决及查找操作的详细步骤。
摘要由CSDN通过智能技术生成

实验五:查找与排序(一):哈希查找

实验内容

针对某个集体(比如你所在的班级)中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序

哈希查找

在开始哈希查找代码的编写之前,首先来简单了解一下哈希查找的概念

非常简单的一句话:“哈希查找是通过计算数据元素的存储地址进行查找的一种方法。”

也就是说,我们可以自定义一种方法,称为哈希函数假设为F,以现有的数据元素作为key,那么在这种自定义方法中对key进行操作,即得到F(key),也就对应着一个存储地址,将这种key–>value的对应关系记录起来就生成哈希表,我们就可以根据key在哈希表中查找到相应元素的位置,完成哈希查找

但是也存在特殊情况,就是两个或多个数据元素的key对应在了同一个地址,这个时候就需要适当的冲突消解策略来处理

看了上述基本描述之后我们,回归正题

哈希查找的操作步骤:

⑴用给定的哈希函数构造哈希表

⑵根据选择的冲突处理方法解决地址冲突

⑶在哈希表的基础上执行哈希查找

基本的地址冲突解决办法可参考这篇博客

本次实验采用除留余数法

实验设计

宏定义

#define H_SIZE 15//哈希表的长度
#define N_SIZE 8//名单长度
#define ERROR 0
#define OK 1
#define R 15//小于哈希表长度的R

1.数据结构的设计

设计哈希函数使其根据自身特点(名称的ascii码值)来对应在哈希表中存储

采用除留余数法

规定R=15,即平均查找长度不超过15,那么哈希函数生成地址为:ascii % R

采用链式结构来避免冲突,即具有相同ascii码值的项必然得到相同的哈希表位,则按照其处理的先后顺序,依次连接到该表位对应的链表末尾

设计两个结构体

typedef struct NameTable{
   
  const char *name;      //姓名
  int ascii;       //对应的ascii码
  int length;       //查找长度
  NameTable* next;
}Name; 
typedef Name* NameArray;

typedef struct HashTable{
   
  int num;//哈希表表位链接点个数
  NameTable* head;
  NameTable* end;
}Hash; 
typedef Hash** Hashlist;
  • NameTable用来存储人名相关信息,查找长度和一个后向指针
  • HashTable即为哈希表,定义对应的链表结点个数,头尾指针
  • 两者合用构造出哈希链

对应于数据整合哈希表建立和基本查找操作,本次实验共有如下函数编写:

描述 对应函数
初始化名单表 void InitNameList
创建hash表,创建哈希函数 void CreatHush
查找函数 void Search
打印名单 void Print_NameList
打印哈希表 void Print_Hash
小菜单显示 void show
主函数 int main

2.核心算法描述

哈希表创建

在主函数中定义

NameArray NameList=NULL;//名单
Hashlist Table=NULL;//哈希表向量

根据名单创建哈希表

void CreatHush(Hashlist &htable,NameArray &NameList)

实现

在函数体中为哈希表Table预先初始化H_SIZE个Hashlist指针向量作为哈希表指针向量,0号单元未用

htable = (Hashlist)malloc((H_SIZE+1) * sizeof(Hash*));//指针向量分配内存//0号单元未用

然后初始化Table为每一个向量所指处分配内存

for (i = 1; i <= H_SIZE; i++) //初始化哈希表//0号单元未用(1-15)
    {
   
      htable[i] = (Hash*)malloc(sizeof(Hash));                                                                     htable[i]->num = 0;     
      htable[i]->head = NULL;
      htable[i]->end = NULL;
    }

之后将NameList内储存的名单信息利用for循环给哈希表赋值,NameList中人名已在InitNameList中初始化完成,也可以在其中自定义更改,或者通过外部文件读写方式读入

此处利用除留取余法定位哈希表对应位置,并考虑有无冲突两种情况

  • 无冲突时哈希表链接点个数值num为初值0,此时直接将其链接至哈希表首链接点head之后
  • 若遇到冲突即num!=0时,则以链式结构解决冲突,即在key位点处找到链表末尾记录,并将此时遭遇冲突记录连接至其末尾
  • 根据记录所在哈希表中查找次数赋值length成员变量,即为前一记录基础上+1,完成哈希表的创建
哈希表查找

哈希查找是在哈希表创建基础上完成,这里假设是将所有班级人员名单均录入其中,生成完整的哈希表,不存在名称正确而找不到情况,当然也可以在判断查找失败之后自定义添加扩充哈希表

考虑一定可以查找到的情况,那么就是从键盘获取学生姓名

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值