使用哈希函数:H(k)=3k MOD 11,并采用链地址法处理冲突。试对关键字序列(22,41,53,46,30,13,01,67)构造哈希表,求等概率情况下查找成功的查找长度,并设计构造哈希表

使用哈希函数:H(k)=3k MOD 11
,并采用链地址法处理冲突。
试对关键字序列(22,41,53,46,30,13,01,67)构造哈希表,
求等概率情况下查找成功的查找长度,并设计构造哈希表的完整算法。  

CODE:

/*
使用哈希函数:H(k)=3k MOD 11
,并采用链地址法处理冲突。
试对关键字序列(22,41,53,46,30,13,01,67)构造哈希表,
求等概率情况下查找成功的查找长度,并设计构造哈希表的完整算法。  
*/

#include <stdio.h>
#include <malloc.h>
#define N 11

typedef struct node{
	int data;//索引 
	struct node* next;//链接冲突的结点 
}node,*pnode;

int a[101] = {22,41,53,46,30,13,01,67};//关键字序列
int size_a = 0;//保存 关键字数组的 长度 
void prin_hash(pnode list[]);//打印哈希表示结点 
void free_hash(pnode list[]);//释放哈希表 //
//build hash list
void create_hash(pnode list[])
{
 
	int i = 0,flag = 0;//i追踪关键字序列,flag获取余数
	int size = sizeof(node);//获取结点大小用于 申请空间 
	//初始哈哈希表 
	for(int i = 0;i < N;i ++)//申请一个哈希表(为每个 下标索引创造一个结点) 
	{
		list[i] = (pnode)malloc(size);//指针,构造一个结点
		list[i]->data = 0;
		list[i]->next = NULL;
	}
	//开始装入 元素,和链接结点处理冲突 
	while(a[i] != 0)
	{
		
		flag = (3 * a[i]) % N;
		if(list[flag]->data == 0)//从没有装载过元素
		{
			list[flag]->data = a[i];//直接赋值
		}	
		else
		{
			pnode p = (pnode)malloc(size);//指针,构造一个结点 
			p->next = NULL;
			p->data = a[i];//本次冲突数据,保存在即将被链接的结点里
			
			pnode q = list[flag];
			//找到该索引链最末尾,链接到末尾 
			while(q->next != NULL)
			{
				q = q->next;
			}
			
			q->next = p;
		}
			 
		i ++;//处理 下一个关键字 
	}
	size_a  = i;//获取 关键字数组的 长度 
	return;
}

//查找哈希上 某个data元素,返回查找其所花费次数 
int search_hash(pnode list[],int data)
{
	pnode q;
	int count = 0;
	int i = (3 * data) % N;//data 对N(这里是11)求余找到 索引链
	if(data == list[i]->data)//data就是索引链头的元素 
	{
		count ++;
	} 
	else//说明要么不存在,要么在其 索引链表上 
	{
		count = count + 1;//索引次数 +1 
		q = list[i];//赋值q为索引链头 
		//开始 查找 整个 索引链 
		while(q != NULL)
		{
			q = q->next;
			count ++;//向后移动一位,说明查找次数+1 
			if(q->data == data)//找到了 count结束增加,退出循环 
			{
				break; 
			}
		}
		if(q == NULL)//如果q为NULL,都没有找到(不是由break退出)
		{
			printf("查找失败,没有该元素!查找了%d次",count);
			return 0;//为查找失败的标识 
		}
		
	}

	return count;//返回 查找data元素,所需要的查找次数 
	
} 

//平均查找长度 
void average_lenth(pnode list[])
{
	double sum = 0;//保存每个元素查找次数之和; 
	//遍历关键字序列 
	for(int i = 0;i < size_a;i ++)
	{ 
		sum += search_hash(list,a[i]);//search_hash返回查找a[i]这个元素的查找次数,a[i]是关键字序列的元素 
	}
	
	printf("总查找次数%.0lf,平均查找长度%.2lf\n",sum,sum/size_a);//size_a是数组中不同元素的个数,这里表示元素的个数(不存在重复数据)(算平均查找长度) 
	return;
}


int main()
{
	pnode list[N];//创造哈希表 长度为11。
	//创建哈希表 
	create_hash(list);
	//查看哈希表上的头结点 元素
	printf("查看哈希表上的头结点元素:");
	prin_hash(list);
	
	//算并打印出 平均查找长度 
	average_lenth(list);
	
	//释放哈希表 
	free_hash(list);
	//查看哈希表释放效果(只有prin_end 即为释放成功)
	printf("查看哈希表释放效果(什么都没有则为释放成功):");
	prin_hash(list);
	
	return 0;
}

//打印哈希表示结点 
void prin_hash(pnode list[])
{
	for(int i = 0;i < N;i ++)
	{
		printf("%d ",list[i]->data);
	}
	printf("\n");
	return;
}

//释放哈希表 
void free_hash(pnode list[])
{
	pnode q,p;
	for(int i = 0;i < N;i ++)
	{
		//从哈希表上的结点开始释放一直到该索引的链都释放结束,然后进行下一个索引的释放 
		q = list[i];
		while(q != NULL)
		{
			p = q->next;
			free(q);
			q = p;
		}
		
		list[i] = NULL;
	}
	
	return;
}

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值