哈希

本文介绍了哈希的概念,包括unordered_set和unordered_map,深入讲解了哈希函数和哈希冲突,以及闭散列(线性探测、二次探测)和开散列(链地址法)等解决冲突的方法。
摘要由CSDN通过智能技术生成

哈希

1.unordered系列关联式容器
1.1unordered_set
int main()
{
   
	unordered_set<int> s;
	//插入操作
	s.insert(1);
	s.insert(4);
	s.insert(2);
	s.insert(5);
	//删除值为1的元素
	s.erase(1);
	//有效元素个数
	s.size();
	//查找值为4的元素
	unordered_set<int>::iterator ret = s.find(4);
	cout << *ret << endl;
	//清空集合
	s.clear();
	//判空操作
	s.empty();

	unordered_set<int> s1{
    1,2,3,4,5,6 };
	//正向迭代器
	unordered_set<int>::iterator it = s1.begin();
	while (it != s1.end())
	{
   
		cout << *it << endl;
		it++;
	}
	return 0;
}
1.2unordered_map
int main()
{
   
	unordered_map<int, int> m;
	//自己显示定义pair插入
	m.insert(pair<int, int>(1, 12));
	m.insert(pair<int, int>(2, 12));
	//使用make_pair函数插入
	m.insert(make_pair(3, 15));
	m.insert(make_pair(4, 102));
	//删除key值为1的元素
	m.erase(1);
	//有效元素个数
	m.size();
	//查找key值为4的元素
	unordered_map<int, int>::iterator ret = m.find(4);
	cout << ret->first << ":" << ret->second << endl;
	//清空集合
	m.clear();
	//判空操作
	m.empty();

	unordered_map<int, int> m1;
	m1.insert(make_pair(1, 12));
	m1.insert(make_pair(2, 12));
	m1.insert(make_pair(3, 15));
	m1.insert(make_pair(4, 102));
	//正向迭代器
	unordered_map<int, int>::iterator it = m1.begin();
	while (it != m1.end())
	{
   
		cout << it->first << ":" << it->second << endl;
		it++;
	}
	cout << endl;
	return 0;
}
2.底层结构

unordered系列的关联式容器之所以效率比较高,是因为其底层使用了哈希结构。

2.1哈希概念

可以不经过任何比较,一次直接从表中得到要搜索的元素。构造出一个结构,通过某种函数(hash func)使元素的储存位置与它的关键码直接能够建立映射的关系,那么在查找时通过该函数可以快速的找到。

插入元素

根据带插入元素的关键字,以此函数计算出该元素的存储位置并按此位置进行存放。

搜索元素

对元素的关键字进行同样的计算,在结构中按此位置取出元素比较,关键码相同则搜索成功。

在这里插入图片描述

2.2哈希冲突

对于两个数据元素的关键字k1和k2(k1!=k2),但是有Hash(k1)==Hash(k2)。即不同关键字通过相同哈希函数计算出相同的哈希地址,这种现象被称为哈希冲突。

2.3哈希函数

引起哈希冲突的一个原因可能是哈希函数设计不够合理,哈希函数的设计原则:

a.哈希函数的定义域必须包括需要存储的全部关键码,而如果散列表允许有m个地址时,其值域必须在0到m-1之间。

b.哈希函数计算出来的地址能均匀分布在整个空间中。

c.哈希函数应该比较简单。

常见的哈希函数

1.直接定制法

取关键字的某个线性函数为散列地址:hash(key)=A*key+B。

2.除留余数法

设散列表中允许的地址数为m,取一个不大于m但是接近或者等于m的质数n作为除数,按照哈希函数:hash(key)=key%n。

3.平方取中法 4.折叠法。 5.随机数法。 6.数学分析法。

哈希函数设计的越精妙,产生哈希冲突的可能性越低,但是无法避免哈希冲突。

2.4哈希冲突解决

解决哈希冲突常见的两种方法是:闭散列和开散列。

2.4.1闭散列

闭散列也叫开放定址法,当发生哈希冲突时,如果哈希表未被装满,说明哈希表中还有空位置,那么可以把key存放到冲突位置中的下一个位置中去。找寻下一个位置的方法有:

1.线性探测

从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止。

插入:通过哈希函数获取等待插入元素在哈希表中的位置。如果该位置没有元素则直接插入,有使用线性探测找到下一个位置插入新元素。

在这里插入图片描述

删除:采用闭散列处理哈希冲突时,不能随便物理删除哈希表中已有的元素,若直接删除元素会影响其他元素的搜索,比如删除9会影响2的查找,因此线性探测采用标记的伪删除法来删除元素。

//EMPTY此位为空,EXITS此位已有元素,DELETE此位元素已删除
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值