本文主要是介绍解决哈希表的冲突-开放地址法和链地址法 ---二次探测再散列的一个人名的例子,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
// hash_test.cpp : Defines the entry point for the console application.
//#include "stdafx.h"
/*
int main(int argc, char* argv[])
{
printf("Hello World!\n");
return 0;
}
*/
#include<iostream>
#include<string>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
using namespace std;
#define HASH_LENGTH 40 //哈希表的长度
#define M 33 //随机数
#define NAME_NO 30 //人名的个数
typedef struct
{
char *py;//名字的拼音
char *name;
int k; //拼音所对应的整数
} NAME;
NAME NameList[HASH_LENGTH]; //全局变量NAME
typedef struct //哈希表
{
char *py; //名字的拼音
char *name;
int k; //拼音所对应的整数
int si; //查找长度/标记被占
} HASH;
HASH HashList[HASH_LENGTH]; //全局变量HASH
void InitNameList() //姓名(结构体数组)初始化
{
char *f;
int r,s0,i;
for (i=0; i<HASH_LENGTH; i++)//★
{
NameList[i].py=(char*)malloc(sizeof(char)*20);//★开辟内存
NameList[i].name=(char *)malloc(sizeof(char)*30);
NameList[i].py[0] = 0;//★
}
/*FILE *pFile;
if((pFile=fopen("D:\\Hash.txt","r"))==NULL)
{
printf("error\n");
exit(1);
}
for(i=0;i<3;i++)
{
fscanf(pFile,"%s",NAME[i].py);
}*/
strcpy(NameList[0].py, "wangmin");//★
strcpy(NameList[1].py, "yinqiang");//★
strcpy(NameList[2].py, "dijuntao");//★
strcpy(NameList[3].py, "sunhaitian");//★
strcpy(NameList[4].py, "gaowendong");//★
strcpy(NameList[5].py, "huoliya");//★
strcpy(NameList[6].py, "yanbing");//★
strcpy(NameList[7].py, "lusida");//★
strcpy(NameList[8].py, "gebilaowang");//★
strcpy(NameList[9].py, "tangqiuhu");//★
strcpy(NameList[10].py, "yangchao");//★
strcpy(NameList[11].py, "wangran");//★
strcpy(NameList[12].py, "jishaopei");//★
strcpy(NameList[13].py, "zhaobingkun");//★
strcpy(NameList[14].py, "hehang");//★
strcpy(NameList[15].py, "liyang");//★
strcpy(NameList[16].py, "chengjingya");//★
strcpy(NameList[17].py, "zhangmeng");//★
strcpy(NameList[18].py, "wangzhenhua");//★
strcpy(NameList[19].py, "zhangliyang");//★
strcpy(NameList[20].py, "zhangyong");//★
strcpy(NameList[21].py, "hehe"); //★
strcpy(NameList[22].py, "jiangmei");//★
strcpy(NameList[23].py, "zhangkexin");//★
strcpy(NameList[24].py, "niuyajue");//★
strcpy(NameList[25].py, "huodan");//★
strcpy(NameList[26].py, "luoqijing");//★
strcpy(NameList[27].py, "zhaocaiyu");//★
strcpy(NameList[28].py, "chenglefeng");
strcpy(NameList[29].py, "huanglaoshi");//*/
strcpy(NameList[0].name, "王敏");//★
strcpy(NameList[1].name, "尹强");//★
strcpy(NameList[2].name, "第军涛");//★
strcpy(NameList[3].name, "孙海天");//★
strcpy(NameList[4].name, "高文东");//★
strcpy(NameList[5].name, "霍立亚");//★
strcpy(NameList[6].name, "闫兵");//★
strcpy(NameList[7].name, "卢思达");//★
strcpy(NameList[8].name, "隔壁老王");//★
strcpy(NameList[9].name, "唐秋虎");//★
strcpy(NameList[10].name, "杨超");//★
strcpy(NameList[11].name, "王然");//★
strcpy(NameList[12].name, "姬少培");//★
strcpy(NameList[13].name, "赵丙坤");//★
strcpy(NameList[14].name, "贺航");//★
strcpy(NameList[15].name, "李阳");//★
strcpy(NameList[16].name, "陈金亚");//★
strcpy(NameList[17].name, "张萌");//★
strcpy(NameList[18].name, "王振华");//★
strcpy(NameList[19].name, "张理洋");//★
strcpy(NameList[20].name, "张勇");//★
strcpy(NameList[21].name, "赫赫"); //★
strcpy(NameList[22].name, "江妹");//★
strcpy(NameList[23].name, "张可心");//★
strcpy(NameList[24].name, "牛亚娟");//★
strcpy(NameList[25].name, "霍丹");//★
strcpy(NameList[26].name, "罗绮靖");//★
strcpy(NameList[27].name, "赵彩宇");//★
strcpy(NameList[28].name, "程乐芬");
strcpy(NameList[29].name, "黄老师");
for(i=0; i<NAME_NO; i++)
{
s0=0;
f=NameList[i].py;
for(r=0; *(f+r)!='\0'; r++)
/* 方法:将字符串的各个字符所对应的ASCII码相加,所得的整数做为哈希表的关键字*/
s0=*(f+r)+s0;
NameList[i].k=s0;
}
}
void CreateHashList() //建立哈希表
{
int i;
for(i=0; i<HASH_LENGTH; i++)
{
HashList[i].py=(char*)malloc(sizeof(char)*20);
HashList[i].name=(char*)malloc(sizeof(char)*30);
HashList[i].py[0] = 0;
HashList[i].name[0]=0;
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;
if(HashList[adr].si==0) //如果不冲突
{
HashList[adr].k=NameList[i].k;
HashList[adr].py=NameList[i].py;
HashList[adr].name=NameList[i].name;
HashList[adr].si=1;
}
else //冲突
{
int j=1;
int h=1;
int b=d;
while ((HashList[d].k!=0)&&(h<=HASH_LENGTH/2))
{
if(j%2==1)//j为奇数时
{
d=(b+h*h)%HASH_LENGTH;
}
else
{
d=(b-h*h)%HASH_LENGTH;
h++;
}
j++;
sum=sum+1;
//查找成功所需查找次数加1
};
HashList[d].k=NameList[i].k;
HashList[d].py=NameList[i].py;
HashList[d].name=NameList[i].name;
HashList[d].si=sum+1;
}
}
}
void FindList() //查找
{
char name_1[20];
int s0=0,r,sum=1,adr,d;
printf("请输入姓名的拼音:\n");
scanf("%s",name_1);
for(r=0; name_1[r]!='\0'; r++) //求出姓名的拼音所对应的整数(关键字)
{
s0+=name_1[r];
}
printf("根据ASCII码值计算关键字为:%d\n",s0);
adr=s0%M; //使用哈希函数
d=adr;
if(HashList[adr].k==s0) //分3种情况进行判断
{
printf("进入表中位置%d进行查找...\n",adr);
//printf("数据匹配!查找成功!输出...\n");
printf("姓名:%s 关键字:%d 查找长度:%d 哈希表中所存在的位置:%d\n",HashList[d].name,s0,sum,d);
}
else if(HashList[adr].k==0)
{
printf("进入表中位置%d进行查找...\n",adr);
printf("哈希表中该位置无数据!查找失败!\n");
printf("无此记录!\n");
}
else
{
printf("进入表中位置%d进行查找...\n",d);
printf("数据不匹配!继续查找...\n");
int g=0;
int b=d;
int j=1;
int h=1;
while(g==0)
{
if(j%2==1)//j为奇数时,+l*l
{
d=(b+h*h)%HASH_LENGTH;
}
else
{
d=(b-h*h)%HASH_LENGTH;
h++;
}
//printf("第 %d 次解决冲突\n",j);
//printf("进入表中位置%d进行查找...\n",d);
printf("%d->",d);
j++;
sum=sum+1;
if(HashList[d].k==0)
{
printf("哈希表中该位置无数据!查找失败!\n");
printf("无此记录!\n");
g=1;
}
else if(HashList[d].k==s0)
{
printf("数据匹配!查找成功!输出...\n");
printf("★**************************************************************★\n");
printf("姓名:%s 关键字:%d 查找长度:%d 哈希表中所存在的位置:%d\n",HashList[d].name,s0,sum,d);
g=1;
}
else
{
//printf("数据不匹配!继续查找...\n");
g=0;
}
}
}
}
void Display() // 显示哈希表
{
int i;
float average=0;
printf("\n地址\t关键字\t\t查找长度\tH(key)\t 姓名\n");
for(i=0; i<HASH_LENGTH; i++)
{
printf("%d",i);
printf("\t%d",HashList[i].k);
printf("\t\t%d",HashList[i].si);
printf("\t\t%d",HashList[i].k%M);
printf("\t%s",HashList[i].name);
printf("\n");
}
for(i=0; i<HASH_LENGTH; i++)
average+=HashList[i].si;
average/=NAME_NO;
printf("平均查找长度:ASL(%d)=%.2f\n",NAME_NO,average);
}
int main()
{
char x;
//system("color 0C");
printf("\n");
printf("\n");
printf("\n");
//printf("★********************************************************************★\n");
printf("\n");
printf(" 【二次探测再散列哈希表】 \n");
printf("\n");
//printf("★********************************************************************★\n");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf(" 信息工程学院");
printf(" 王敏\n");
printf(" 学号:2010012851\n");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf("_______________");
system("PAUSE");
system("cls");
/*printf("★********************************************************************★\n");
printf("★********** 【二次探测再散列哈希表】 ***************★\n");
printf("★********************************************************************★\n");*/
printf("\n");
printf("\n");
InitNameList();
CreateHashList ();
printf(" ★★****************★★\n");
printf(" ★ 1.显示哈希表 ★\n");
printf(" ★ 2.查找 ★\n");
printf(" ★ 0.退出 ★ \n");
printf(" ★ 请选择... ★ \n");
printf(" ★★****************★★ \n");
while(cin>>x)
{
system("cls");
if(x=='1')
{
printf("\n");
printf("****************************哈希表********************************\n");
printf("\n");
printf("★**哈希表长: %d **★\n",HASH_LENGTH);
printf("★**表中数据个数:%d **★\n",NAME_NO);
printf("★**随机函数: %d **★\n",M);
Display();
printf("★**************************************************************★\n");
printf("请再次选择...");
}
else if(x=='2')
{
FindList();
printf("★**************************************************************★\n");
printf("★★****************★★\n");
printf("★ 1.显示哈希表 ★★\n");
printf("★ 2.查找 ★★\n");
printf("★ 0.退出 ★★ \n");
printf("★ 请选择... ★★ \n");
printf("★★****************★★ \n");
}
else if(x=='0')
{
printf("欢迎下次使用!再见!");
exit(1);
}
else
{
printf("请按提示操作!谢谢!不要调戏我的智商!谢谢!\n");
}
}
for (int i=0; i<HASH_LENGTH; i++)
{
free(NameList[i].py);
free(HashList[i].py);
free(NameList[i].name);
free(HashList[i].name);
}
return 0;
}
这篇关于解决哈希表的冲突-开放地址法和链地址法 ---二次探测再散列的一个人名的例子的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!