c语言数据结构有关哈希表的,要添加一个查找函数,具体程序看补充 50
#defineNAME_NO30/*人名的个数*/#defineMAXLISTLEN30#defineMAXNAME80/*最长的姓名*/typedefstructrec...
#define NAME_NO 30 /*人名的个数*/
#define MAXLISTLEN 30
#define MAXNAME 80 /*最长的姓名*/
typedef struct record
{
int key;
char name[MAXNAME];
struct record *next;
}Record,RECF[MAXLISTLEN];
int modh(int,int);
void chainh(char *name ,RECF ,int,int (*hash)(int,int));
void prhashlist(int,RECF ); /*输出散列表*/
int NameToKey(char *name); /*字符转换为关键字*/
void InputAndCreateHR(int num,int listlen,RECF r); /*输入姓名并创建哈希表*/
int HashLen(int n);
int is(int x); /*判断x是否为素数*/
void main(void)
{
int num=NAME_NO; /*姓名个数*/
RECF r; /*哈希表*/
int listlen; /*实际哈希表的长度*/
listlen=HashLen(num); /*确定哈希表实际长度*/
InputAndCreateHR(num,listlen,r); /*输入姓名并创建哈希表*/
prhashlist(listlen,r); /*显示哈希表*/
}
/*
用链地址法解决冲突的散列造表算法,根据(*hash)()函数造散列表
其中参数int(*hash)()是指向函数的指针,它返回一个整数(散列地址)
*/
void chainh(char *name,RECF r,int listlen,int (*hash)(int,int))
{
int addr;
Record *p,*q;
int k;
k=NameToKey(name); /*把拼音转换为关键字*/
addr=(*hash)(k,listlen);
if (!r[addr].key) /*建立链表,地址相等的情况*/
{
r[addr].key=k; /*插入*/
strcpy(r[addr].name,name);
}
else if(r[addr].key!=k) /*建立链表地址没有冲突的情况*/
{
p=r[addr].next;
q=&r[addr];
while(p && p->key!=k) /*内容不空且其地址与该地址不等*/
{
q=p; p=p->next; /*插入*/
}
if(!p) /*建立地址内容为空的链表结点*/
{
p=(Record *)malloc(sizeof(Record));
p->key=k;
strcpy(p->name,name);
p->next=NULL;
q->next=p;
}
}
}
/* Hash函数(除留余数法) */
int modh(int k,int listlen)
{
return(k % listlen); /*返回模的值*/
}
/* 输出散列表 */
void prhashlist(int listlen,RECF r)
{
int i;
Record *p;
printf("哈希地址\t链表\n");
for(i=0;i<listlen;i++) /*按顺序输出关键字的地址位置,值,建立的链表*/
{
if(!r[i].key) /*如果该地址中内容为空*/
printf("%d\t\t^\n",i);
else
{
printf("%d\t%s(%d)-->",i,r[i].name,r[i].key);
p=r[i].next;
while(p)
{
printf("%s(%d)-->",p->name,p->key);
p=p->next;
}
printf("^\n");
}
}
}
/* 把拼音字符转换对应的ASCII */
int NameToKey(char *name)
{
int value=0;
int i,len;
len=strlen(name);
for(i=0;i<len;i++)
value+=*(name+i);
return value;
}
int is(int x)
{
int i,k;
k=(int)sqrt(x);
for(i=2;i<=k;i++)
if(x%k==0)return 0;
return 1;
}
/* 根据数据量n,限定平均查找次数为2*/
int HashLen(int n)
{
int m;
m=n/2;
while(m>2 && !is(m))m--;
return m;
}
void InputAndCreateHR(int num,int listlen,RECF r)
{
int i;
char name[MAXNAME];
for(i = 0;i < listlen;i++)
{
r[i].key = 0;
r[i].name[0]='\0';
r[i].next = NULL;
}
printf("输入%d个姓名(每行一个):\n",num);
for(i=0;i<num;i++)
{
gets(name);
chainh(name,r,listlen,modh);
}
} 展开
#define MAXLISTLEN 30
#define MAXNAME 80 /*最长的姓名*/
typedef struct record
{
int key;
char name[MAXNAME];
struct record *next;
}Record,RECF[MAXLISTLEN];
int modh(int,int);
void chainh(char *name ,RECF ,int,int (*hash)(int,int));
void prhashlist(int,RECF ); /*输出散列表*/
int NameToKey(char *name); /*字符转换为关键字*/
void InputAndCreateHR(int num,int listlen,RECF r); /*输入姓名并创建哈希表*/
int HashLen(int n);
int is(int x); /*判断x是否为素数*/
void main(void)
{
int num=NAME_NO; /*姓名个数*/
RECF r; /*哈希表*/
int listlen; /*实际哈希表的长度*/
listlen=HashLen(num); /*确定哈希表实际长度*/
InputAndCreateHR(num,listlen,r); /*输入姓名并创建哈希表*/
prhashlist(listlen,r); /*显示哈希表*/
}
/*
用链地址法解决冲突的散列造表算法,根据(*hash)()函数造散列表
其中参数int(*hash)()是指向函数的指针,它返回一个整数(散列地址)
*/
void chainh(char *name,RECF r,int listlen,int (*hash)(int,int))
{
int addr;
Record *p,*q;
int k;
k=NameToKey(name); /*把拼音转换为关键字*/
addr=(*hash)(k,listlen);
if (!r[addr].key) /*建立链表,地址相等的情况*/
{
r[addr].key=k; /*插入*/
strcpy(r[addr].name,name);
}
else if(r[addr].key!=k) /*建立链表地址没有冲突的情况*/
{
p=r[addr].next;
q=&r[addr];
while(p && p->key!=k) /*内容不空且其地址与该地址不等*/
{
q=p; p=p->next; /*插入*/
}
if(!p) /*建立地址内容为空的链表结点*/
{
p=(Record *)malloc(sizeof(Record));
p->key=k;
strcpy(p->name,name);
p->next=NULL;
q->next=p;
}
}
}
/* Hash函数(除留余数法) */
int modh(int k,int listlen)
{
return(k % listlen); /*返回模的值*/
}
/* 输出散列表 */
void prhashlist(int listlen,RECF r)
{
int i;
Record *p;
printf("哈希地址\t链表\n");
for(i=0;i<listlen;i++) /*按顺序输出关键字的地址位置,值,建立的链表*/
{
if(!r[i].key) /*如果该地址中内容为空*/
printf("%d\t\t^\n",i);
else
{
printf("%d\t%s(%d)-->",i,r[i].name,r[i].key);
p=r[i].next;
while(p)
{
printf("%s(%d)-->",p->name,p->key);
p=p->next;
}
printf("^\n");
}
}
}
/* 把拼音字符转换对应的ASCII */
int NameToKey(char *name)
{
int value=0;
int i,len;
len=strlen(name);
for(i=0;i<len;i++)
value+=*(name+i);
return value;
}
int is(int x)
{
int i,k;
k=(int)sqrt(x);
for(i=2;i<=k;i++)
if(x%k==0)return 0;
return 1;
}
/* 根据数据量n,限定平均查找次数为2*/
int HashLen(int n)
{
int m;
m=n/2;
while(m>2 && !is(m))m--;
return m;
}
void InputAndCreateHR(int num,int listlen,RECF r)
{
int i;
char name[MAXNAME];
for(i = 0;i < listlen;i++)
{
r[i].key = 0;
r[i].name[0]='\0';
r[i].next = NULL;
}
printf("输入%d个姓名(每行一个):\n",num);
for(i=0;i<num;i++)
{
gets(name);
chainh(name,r,listlen,modh);
}
} 展开
2个回答
展开全部
现在还需要解答么?
追问
已经解决了,呵呵
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
先占个位置看看,对了,最好把你的问题描述的清楚一点,不知道你这个到底是什么问题呀!
追问
这个程序本来是输入30个姓名,用链表来解决冲突,输出了哈希表,现在我想加个查找人名的程序,在输出哈希表后,输入姓名看姓名存不存在在哈希表中,希望能快点帮我解决一下,赶时间
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询