哈希算法

一、学习要点:
1.哈希表是一个很神奇的东西,即解决了数组的增删的繁琐,也解决了链表的查找问题;
2.哈希表的哈希函数;
3.哈希表的冲突问题解决;什么叫做闭散列,什么叫做开散列;闭,严重遵守哈希内涵。开,有点开放的意味,解决冲突靠链表,有点变味的哈希;
二、相关数据结构解读:
1.构造一种存储结构,通过某种函数使元素的存储位置与它的关键码之间建立一种一一映射的关系,那么在查找时通过该函数可以很快找到该元素;
2.哈希函数是用来得到给定key值在哈希表中的存储位置的;
3.哈希函数也并不是固定的,可以自己根据情况来定,一般常用常见的有直接定制法,除留余数法,平方取中法,折叠法,随机数法,数学分析法。
4.当向该结构插入元素时,存在根据关键码和哈希函数来计算出位置,当搜索时,也是根据给定的码值,用哈希函数进行转化得到存储位置进行查找,将得到位置的值和要查找的关键码进行比对,若关键码相同,则搜索成功,否则根据解决冲突的方法,继续查找;

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h> 

#define OK 1;
#define ERROR 0;
#define SUCCESS 1
#define UNSUCCESS 0
#define Status int
#define HASHSIZE 12	//定义散列表长为数组的长度 
#define NULLKEY -32768

typedef struct
{
	int *elem;	//数据元素存储基址,动态分配数组 
	int count;	//当前数据元素个数 
}HashTable;

int m = 0; 	//散列表表长,全局变量
//初始化散列表
Status InitHashTable(HashTable *H)
{
	int i;
	m = HASHSIZE;
	H->count = m;
	H->elem = (int *)malloc(m*sizeof(int));
	for(i = 0; i < m;i ++)
		H->elem[i] = NULLKEY;
	return OK;
 } 
 //散列函数 
int Hash(int key)
{
	return key % m;	//除留余法 
}
// 输入关键字进散列表
void InsertHash(HashTable *H,int key)
{
	int addr = Hash(key);//求散列地址
	while(H->elem[addr] != NULLKEY)	//如果不为空,则冲突 
		addr = (addr + 1) % m;	//开放定址法的线性探测 
	H->elem[addr] = key; //直到有空位后插入关键字 
} 
//散列表查找关键字
Status SearchHash(HashTable H,int key,int *addr)
{
	*addr = Hash(key);	//求散列地址 
	while(H.elem[*addr] != key)	//如果不为空,则冲突 
	{
		*addr = (*addr + 1) % m;	//开放地址法的线性探测 
		if(H.elem[*addr] == NULLKEY || *addr == Hash(key))
		{//如果循环回到原点 
			return UNSUCCESS;	//则说明关键字不存在 
		}
	}
	return *addr; 	//返回查找到地址 
 } 
 
int main()
{
	int a[12] = {12,67,56,16,25,37,22,29,15,47,48,34};
	HashTable H;
	InitHashTable(&H);
	for(int i = 0;i < m; i++)
		InsertHash(&H,a[i]);
	printf("---插入之后的哈希表为:-------\n");
	for(int i = 0;i < m ;i ++)
		printf("%d ",H.elem[i]);
	int addr,j;
	j = SearchHash(H,a[5],&addr);
	printf("搜索到a[5]的地址是:%d",j);
	return 0;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值