实验九查找

实验九查找

实现哈希表的构造和查找算法,要求:用除留余数法构造哈希函数,分别采用二次探测再散列、链地址法解决冲突。

#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);
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值