实验九查找
实现哈希表的构造和查找算法,要求:用除留余数法构造哈希函数,分别采用二次探测再散列、链地址法解决冲突。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct{
int key;
}keytype;
typedef struct {
keytype elem[100];
int length; /*当前的长度*/
int size; /*哈希表的总长*/
}node;
typedef struct LNode
{
int data; //节点的数据域,存放要插入节点
struct LNode *next; //链接指针域
}*LNODE, LNode;//哈希表的表头后带链表结构
typedef struct HashNode
{
int Data;//头节点,存放该表头号
int count; //存放该表头连接的节点数
LNode *first; //链接的第一个指针域
}*HN, HashNode;
int c = 0, b = 0;
int pianyi(int i, int t)
{
if(i%2==0)
{
t=t+pow(c++,2);
}
else
{
t=t-pow(b++,2);
}
return t;
}
int quyu(node h, int k)//取余
{
return k%(h.size);
}
int initnode(node *h)//初始化二次探测
{
int i;
for(i=0; i < h->size; i++){
h->elem[i].key=-1;
}
}
void creat(node *h, HashNode hash[],int a[])
{
int i, j, x, t, r;
j=0;
initnode(h);
//二次探测
for(;j<h->length;j++)
{
r=quyu(*h,a[j]);
if(h->elem[r].key==-1)
h->elem[r].key=a[j];
else
{
t=r;
i=0;
while(h->elem[r].key!=-1&&h->elem[r].key!=a[j]&&i<h->size/2)
{
r=pianyi(i,t);
i++;
}
b=0;c=0;
h->elem[r].key=a[j];
}
}
//链地址
LNode *p,*q;
int flag = 0;
for(j = 0; j < h->size; j++)
{
hash[j].Data = j%h->size;//标记表头
hash[j].first = NULL; //初始化为空
hash[j].count = 0; //计数器清零
}
for(i=0;i<h->length;i++)
{
int k;
k = a[i]%h->size;
flag = 0;
for(j = 0; j < h->size; j++)
{
for(q = hash[j].first; q; q=q->next)
{
if(q->data == a[i])
{
flag=1; //若出现过则标记
}
}
if(k == hash[j].Data&&!flag)
{
p=(LNode *)malloc(sizeof(LNode));
p->data = a[i];
if(!hash[j].count)
{
hash[j].first = p;//头节点链接
}
else
{
for(q = hash[j].first; q->next; q=q->next);
q->next=p;//链接
}
p->next = NULL;//置空
hash[j].count++;//计数器加一
}
}
}
}
int Search2(node H, int k){
int p, i=0, t=0;
p=quyu(H,k);
while(H.elem[p].key !=-1&&k!=H.elem[p].key)//该地址中有记录,并且关键字不相等
{
p = pianyi(i,t); // 用二次探测法求的下一个探测的地址
i++;
}
if(k == H.elem[p].key)
return p;
else
return -1;
}
void Search1(HashNode hash[],int m,int key){
int i;
int count;
LNode *p;
for(i=0;i<m;i++)
{
count=0;
for(p=hash[i].first;p;p=p->next)
{
count++;
if(p->data==key)
{
printf("\n位于hash[%d]的第%d个位置\n",i,count);
exit(0);
}
}
}
printf("\n没有找到!\n");
}
void print2(node *h)
{
int i;
for(i=0; i<h->size; i++){
printf("%-4.2d",i);
}
printf("\n");
for(i=0; i < h->size; i++){
printf("%-4.2d",h->elem[i].key);
}
}
void print1(HashNode hash[],int m)
{
int i;
LNode *p;//操作指针
for(i=0;i<m;i++)
{
printf("%d:", i, hash[i].count);
for(p=hash[i].first; p; p=p->next)
{
printf(" %d ",p->data);
}
printf("\n");
}
}
int main()
{
node t;
int i, key, c;
HashNode hash[20];
int a[10] = {22, 47,23, 43, 54, 90, 46, 31, 29, 98};
printf("数据为:");
for(int i = 0; i < 10; i++){
printf("%d ", a[i]);
}
printf("\n除数为:13\n");
t.length = 10;
t.size = 13;
creat(&t, hash, a);
printf("\n采用二次探测再散列的哈希表:\n");
print2(&t);
printf("\n输入要查找的key:");
scanf("%d",&key);
c = Search2(t, key);
if(c != -1){
printf("位置为:%d\n",c);
}
else{
printf("没有找到!\n");
}
printf("\n采用链地址法的哈希表\n");
print1(hash,t.size);
printf("输入要查找的key:");
scanf("%d",&key);
Search1(hash, t.size, key);
}