数据结构实验(五)

1.实验题目

    针对某个集体中人名设计一个哈希表,使得平均查找长度不超过 R,并完成相应的建表和查表程序。假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有 30 个,取平均查找 长度的上限为 哈希函数用除留余数法构造,用线性探测再散列法或链地址法处理冲突。

2.需求分析

需将姓名拼音转化为数字才能比较

哈希表冲突后的探测使用线性探测法

采用数组形式进行存储

3.概要设计

 存储数据包括 拼音 地址 查找次数,查找长度

 哈希表的存储过程

 根据关键字查找

 函数的调用

#define NAME_NO 30
#define HASH_LENGTH 50
#define M 50


typedef struct

{
   char *py;
   int k;
}NAME;



typedef struct
{
   char *py;
   int k;
   int si;
}HASH;



NAME NameList[30];
HASH HashList[HASH_LENGTH];

4:主要算法设计

(1)姓名(结构体数组)初始化

名字以拼音的形式够成字符串,将字符串的各个字符所对应的ASCII码相加,所得的整数做为哈希表的关键字。

void init_namelist()
{
	int i;	 
	int j;
	int s0;
	char *p;
 
	NameList[0].py="chenliang";//陈亮  
    NameList[1].py="chenyuanhao";//陈元浩  
    NameList[2].py="chengwenliang";//程文亮  
    NameList[3].py="dinglei";//丁磊  
    NameList[4].py="fenghanzao";//冯汉枣  
    NameList[5].py="fuzongkai";//付宗楷  
    NameList[6].py="hujingbin";//胡劲斌  
    NameList[7].py="huangjianwu";//黄建武  
    NameList[8].py="lailaifa";//赖来发  
    NameList[9].py="lijiahao";//李嘉豪  
    NameList[10].py="liangxiaocong";//梁晓聪  
    NameList[11].py="linchunhua";//林春华  
    NameList[12].py="liujianhui";//刘建辉  
    NameList[13].py="luzhijian";//卢志健  
    NameList[14].py="luonan";//罗楠  
    NameList[15].py="quegaoxiang";//阙高翔  
    NameList[16].py="sugan";//苏淦  
    NameList[17].py="suzhiqiang";//苏志强  
    NameList[18].py="taojiayang";//陶嘉阳  
    NameList[19].py="wujiawen";//吴嘉文  
    NameList[20].py="xiaozhuomin";//肖卓明  
    NameList[21].py="xujinfeng"; //许金峰  
    NameList[22].py="yanghaichun";//杨海春  
    NameList[23].py="yeweixiong";//叶维雄  
    NameList[24].py="zengwei";//曾玮  
    NameList[25].py="zhengyongbin";//郑雍斌  
    NameList[26].py="zhongminghua";//钟明华  
    NameList[27].py="chenliyan";//陈利燕  
    NameList[28].py="liuxiaohui";//刘晓慧  
    NameList[29].py="panjinmei";//潘金梅 
 
	for (i=0; i<NAME_NO; i++)
	{
		s0 = 0;
		p = NameList[i].py;
		for (j=0; *(p+j)!='\0'; j++)			
		{
			s0 += *(p+j);		
		}
		NameList[i].k = s0;
		printf("%13s %d\n", NameList[i].py, NameList[i].k%M );
	}
}

(2)  建立哈希表   

      用除留余数法构建哈希函数,用伪随机探测再散列法处理冲突

void CreateHashList()
{
	int i ;		
	int j;
	int collision_cnt = 0;
 
	for (i=0; i<HASH_LENGTH; i++)
	{
		HashList[i].py = "";
		HashList[i].k = 0;
		HashList[i].si = 0;
	}
	
	for (i=0; i<NAME_NO; i++)
	{
		int sum = 0;
		int adr = (NameList[i].k)%M;
		int d = adr;
 
		collision_cnt = 0;
 
		if (HashList[adr].si == 0)
		{
			printf("\e[48;5;9m success adr %d\e[0m\n", d);
			HashList[adr].k = NameList[i].k;
			HashList[adr].py = NameList[i].py;
			HashList[adr].si=1;
		}
		else
		{
			do
			{
				collision_cnt++;
				printf("collision adr=%d\n", d);
				d = (d+NameList[i].k%10+1)%M;
				sum +=1;
				printf("new adr %d, collision_cnt = %d\n",d,  collision_cnt);
				if (collision_cnt>10) 
				{
					printf("*******fail********\n");
					goto out;
				}
			}while(HashList[d].k != 0);	
 
			printf("\e[48;5;9m success adr %d\e[0m\n", d);
		
			HashList[d].k = NameList[i].k;
			HashList[d].py = NameList[i].py;
			HashList[d].si = sum+1;
		}
	}
	
out:
 
	printf("----------------------------------------\n");
	j = 0;
	for(i=0; i<HASH_LENGTH; i++)	
	{
			
		if (HashList[i].k != 0)	
		{
			j++;
			printf("%d:%13s, %d, %d\n",i, HashList[i].py, HashList[i].k, HashList[i].si );	
		}
		else
		{
			printf("%d:empty!\n", i);		
		}
	}
 
	printf("-----------totall = %d-------------\n", j);
}

(3)  查找哈希表
void FindList()
{
	char name[20] = {0};
	int adr;
	int d;
	int sum=1;
	int i;
	int s0 = 0;
 
	printf("please input pinyin\n");
	scanf("%s", name);
 
	for (i=0; i<20; i++)
	{
		if(name[i] != '\0')
		s0 += name[i];
	}
 
	printf("to find: name:%s, key:%d\n", name, s0);
	
	adr = s0%M;
	d = adr;
		
	if ((HashList[adr].k == s0) && (strcmp(HashList[adr].py, name) == 0))
		printf("find name:%s key=%d, length=1\n", HashList[d].py, s0);
	else if (HashList[adr].k == 0)
		printf("no record\n");
	else
	{
		do
		{
			d = (d+s0%10+1)%M;
			sum++;
			if (HashList[d].k == 0)
			{
				printf("no record!\n");	
				break;
			}
			
			if ((HashList[d].k == s0) && (strcmp(HashList[d].py, name) == 0))
			{
				printf("find name:%s, key:%d, search_len=%d\n", HashList[i].py, s0, sum);	
				break;
			}
 
		}while(1);	
	}
 
}

4.详细设计

#include <stdio.h>
#include <string.h>
#include <unistd.h>
 
#define NAME_NO 30
#define HASH_LENGTH 50 
#define M 50
 
typedef struct
{
	char *py;
	int k;
}NAME;
 
typedef struct 
{
	char *py;
	int k;
	int si;
}HASH;
 
 
NAME NameList[30];
HASH HashList[HASH_LENGTH];
 
void init_namelist()
{
	int i;	 
	int j;
	int s0;
	char *p;
 
	NameList[0].py="chenliang";//陈亮  
    NameList[1].py="chenyuanhao";//陈元浩  
    NameList[2].py="chengwenliang";//程文亮  
    NameList[3].py="dinglei";//丁磊  
    NameList[4].py="fenghanzao";//冯汉枣  
    NameList[5].py="fuzongkai";//付宗楷  
    NameList[6].py="hujingbin";//胡劲斌  
    NameList[7].py="huangjianwu";//黄建武  
    NameList[8].py="lailaifa";//赖来发  
    NameList[9].py="lijiahao";//李嘉豪  
    NameList[10].py="liangxiaocong";//梁晓聪  
    NameList[11].py="linchunhua";//林春华  
    NameList[12].py="liujianhui";//刘建辉  
    NameList[13].py="luzhijian";//卢志健  
    NameList[14].py="luonan";//罗楠  
    NameList[15].py="quegaoxiang";//阙高翔  
    NameList[16].py="sugan";//苏淦  
    NameList[17].py="suzhiqiang";//苏志强  
    NameList[18].py="taojiayang";//陶嘉阳  
    NameList[19].py="wujiawen";//吴嘉文  
    NameList[20].py="xiaozhuomin";//肖卓明  
    NameList[21].py="xujinfeng"; //许金峰  
    NameList[22].py="yanghaichun";//杨海春  
    NameList[23].py="yeweixiong";//叶维雄  
    NameList[24].py="zengwei";//曾玮  
    NameList[25].py="zhengyongbin";//郑雍斌  
    NameList[26].py="zhongminghua";//钟明华  
    NameList[27].py="chenliyan";//陈利燕  
    NameList[28].py="liuxiaohui";//刘晓慧  
    NameList[29].py="panjinmei";//潘金梅 
 
	for (i=0; i<NAME_NO; i++)
	{
		s0 = 0;
		p = NameList[i].py;
		for (j=0; *(p+j)!='\0'; j++)			
		{
			s0 += *(p+j);		
		}
		NameList[i].k = s0;
		printf("%13s %d\n", NameList[i].py, NameList[i].k%M );
	}
}
 
void CreateHashList()
{
	int i ;		
	int j;
	int collision_cnt = 0;
 
	for (i=0; i<HASH_LENGTH; i++)
	{
		HashList[i].py = "";
		HashList[i].k = 0;
		HashList[i].si = 0;
	}
	
	for (i=0; i<NAME_NO; i++)
	{
		int sum = 0;
		int adr = (NameList[i].k)%M;
		int d = adr;
 
		collision_cnt = 0;
 
		if (HashList[adr].si == 0)
		{
			printf("\e[48;5;9m success adr %d\e[0m\n", d);
			HashList[adr].k = NameList[i].k;
			HashList[adr].py = NameList[i].py;
			HashList[adr].si=1;
		}
		else
		{
			do
			{
				collision_cnt++;
				printf("collision adr=%d\n", d);
				d = (d+NameList[i].k%10+1)%M;
				sum +=1;
				printf("new adr %d, collision_cnt = %d\n",d,  collision_cnt);
				if (collision_cnt>10) 
				{
					printf("*******fail********\n");
					goto out;
				}
			}while(HashList[d].k != 0);	
 
			printf("\e[48;5;9m success adr %d\e[0m\n", d);
		
			HashList[d].k = NameList[i].k;
			HashList[d].py = NameList[i].py;
			HashList[d].si = sum+1;
		}
	}
	
out:
 
	printf("----------------------------------------\n");
	j = 0;
	for(i=0; i<HASH_LENGTH; i++)	
	{
			
		if (HashList[i].k != 0)	
		{
			j++;
			printf("%d:%13s, %d, %d\n",i, HashList[i].py, HashList[i].k, HashList[i].si );	
		}
		else
		{
			printf("%d:empty!\n", i);		
		}
	}
 
	printf("-----------totall = %d-------------\n", j);
}
 
void FindList()
{
	char name[20] = {0};
	int adr;
	int d;
	int sum=1;
	int i;
	int s0 = 0;
 
	printf("please input pinyin\n");
	scanf("%s", name);
 
	for (i=0; i<20; i++)
	{
		if(name[i] != '\0')
		s0 += name[i];
	}
 
	printf("to find: name:%s, key:%d\n", name, s0);
	
	adr = s0%M;
	d = adr;
		
	if ((HashList[adr].k == s0) && (strcmp(HashList[adr].py, name) == 0))
		printf("find name:%s key=%d, length=1\n", HashList[d].py, s0);
	else if (HashList[adr].k == 0)
		printf("no record\n");
	else
	{
		do
		{
			d = (d+s0%10+1)%M;
			sum++;
			if (HashList[d].k == 0)
			{
				printf("no record!\n");	
				break;
			}
			
			if ((HashList[d].k == s0) && (strcmp(HashList[d].py, name) == 0))
			{
				printf("find name:%s, key:%d, search_len=%d\n", HashList[i].py, s0, sum);	
				break;
			}
 
		}while(1);	
	}
 
}
 
 
int main(void)
{
	init_namelist();
	CreateHashList();
	FindList();
 
	return 0;
}

5.调试分析

      在创建时未加入可以从屏幕输入的创建方式,采用的是在程序创建时已将规定好的数据创建。

6.使用说明

  1.显示

  2.查找

  3.退出

选择规定的选项进行相应的操作,对于查找部分是对关键字进行的查找。

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值