哈希(Hash)算法,用哈希表进行查找

众所周知,哈希表是一种时间复杂度低的查找方式,而它的实现原理也比较简单。

举个简单的例子,如果我报一个字:中,让你去找到这个字在字典里的位置,你会怎么做?

首先,我们知道,这个字念:zhong,故我们采取拼音查字法,找到声母:zh,然后再去这个声母下找到韵母:ong,接着,就可以根据zhong这个音所标识的页码,去字典里找到这个字了。

哈希查找,就是一种这样的方法。

字典里的字茫茫多,如果采用最原始的遍历查找法,就如同让你从第一页第一个字开始,一直遍历到你所需要的字为止,这显然是非常浪费时间的。而哈希表,就如同字典前面的拼音检字表和部首检字表。它把元素按照一定的规律(H(key))分类存储于一张“哈希表”中,当我们需要查找某个元素时,就可以通过它的特征,快速找到我们需要的元素。

当然,正如同我们中文里有很多同音字,采取拼音检字表必然会有好几个不同的字,采用同一个音所占据的页面的情况一样,哈希表也不可避免的会出现不同元素的哈希值相同的情况,故,业界也采用了各种各样的方案,来规避这种影响。比如对哈希值相同的元素,再次使用哈希函数等。而本文,我们将采用一中一劳永逸的方法,这种方法也类似于字典。我们把哈希值相同的元素,放入了一个以hash[ i ]为首地址的链表中,这样找到哈希值后就可以直接遍历快速筛选出我们要查找的元素。

接下来我们用代码实现

hash.h文件
/*********************************************/
#ifndef __HASH_H__
#define __HASH_H__
#define   N   10              //数组长度
#define   P   13              //哈希表


typedef int datatype;    
typedef struct Node             //定义链表
{
	datatype data;//数据域
	struct Node *next;  //指针域
}Node;


//初始化哈希表
void init_hash(Node *hash[]);
	
//将元素存入哈希表
int insert_hash(Node *hash[], int x);

//定义查看哈希表函数
void show_hash(Node *hash[]);

//定义哈希查找函数
void search_hash(Node *hash[], int key);


#endif

首先要初始化哈希表

//初始化哈希表
void init_hash(Node *hash[])
{
	for(int i=0; i<P; i++)
	{
		hash[i] = NULL;
	}

	printf("初始化成功\n");
}

接下来,我们要把元素存入哈希表


//将元素存入哈希表
int insert_hash(Node *hash[], int x)
{
	int index = x%P;   //定位存储的链表
	//封装x进节点
	Node *q = (Node*)malloc(sizeof(Node));
	if(NULL == q)    //判断是否申请节点成功
	{
		printf("申请失败\n");
		return -1;
	}
	q->data = x;
	q->next =NULL;

	//使用头插法,节点入链表
	q->next = hash[index]; 
    //存储第一个元素时,因为hash[index]是NULL,故等价于q->next = NULL
	
    hash[index] = q;   //现在hash[index]里是一个指向NULL的q
					   //相当于把头节点替换成q
}

定义查看哈希表函数


//定义查看哈希表函数
void show_hash(Node *hash[])
{
	for(int i=0; i<P; i++)
	{
		printf("%d:", i);
		Node *q = hash[i];    //定义遍历哈希表
		while(q!=NULL)
		{
			printf("%d->",q->data);
			q = q->next;
		}
		printf("NULL\n");
	}
}

这样,我们就完成一张哈希表,也能查看哈希表内的数值了

然就是哈希表最重要的功能:查找。不过其实也不难就是了

//定义哈希查找函数
void search_hash(Node *hash[], int key) //哈希表与值
{
	int index = key%P;  //定位值所在的链表

	//定义遍历指针遍历哈希表
	Node *q = hash[index];
	while(q!=NULL && q->data!=key)
	{
		q=q->next;
	}
	
	//对找到的节点判断
	if(NULL==q)
	{
		printf("查找失败\n");
	}else
	{
		printf("查找成功\n");
	}
}

主函数内容,就交给你们自己实现啦

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老K殿下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值