29.哈希(下)

实现哈希表:

这样看起来可以实际不可以,

这几个值互相抢位置,比如说找20,在模10位置找,找不到下一个位置找。直到空停止,但是如果删除30,再去查找20,9位置没值,直接停了。这还有三个枚举值存在 空 删除,删除了,标记成删除,删除状态继续往后找。哈希冲突越多效率越低。

cpp 复制代码
#pragma once
#include<vector>

enum State
{
	EXIST,
	EMPTY,
	DELETE
};

template<class K, class V>
struct HashData
{
	pair<K, V> _kv;
	State _state = EMPTY;
};

template<class K, class V>
class HashTable
{
public:
	HashTable()
		:_tables(11)
		,_n(0)
	{}
private:
	vector<HashData<K, V>> _tables;
	size_t _n;  // 记录数据个数
};

这里模capacity的话,,打个比方,如果容量是20,size 11 ,

vector operator【】会检查越没越界,等不等于size。顺序表要线性存储,不能直接存,要模size

尽量让size capacity一样大,比如说这里,size和capacity都是11,

基础哈希表就写完了。

满了就死循环了,

扩容:有点差

新方式:

如果搞新vector要自己计算位置,搞新哈希表,把里面vector扩到二倍,遍历旧表,把旧表数据insert到新表,不会再次扩容,因为已经扩了二倍了,负载因子最多0.3到不了扩容,就复用了这个逻辑。

为什么这里必须支持等于,给一个等于的仿函数。查找插入紧紧和等于相关。

插入不允许冗余,

cpp 复制代码
int main()
{
	//int a[] = { 19,30,52,63,11,22 };
	int a[] = { 19,30,5,36,13,20,21,12 };
	HashTable<int, int> ht;
	for (auto e : a)
	{
		ht.Insert({ e, e });
	}

	//ht.Insert({ 15, 15 });

	ht.Erase(30);
	if (ht.Find(20))
	{
		cout << "找到了" << endl;
	}

	if (ht.Find(30))
	{
		cout << "找到了" << endl;
	}
	else
	{
		cout << "没有找到" << endl;
	}

	return 0;
}

验证一下

用二次检测解决群集,堆积问题

二次探测就是让更分散

w往右回绕是模往左回绕是加。

这只是逻辑不验证了。

直接加i平方就行。

互相占还是不好。哈希桶好

大小要是素数但是这里不是素数。解决1:

选了一堆素数表,接近二倍。改造我们的代码:

会取比0大的素数,53,

就是写死了一组值。

相关推荐
阿昭L2 小时前
leetcode链表是否有环
算法·leetcode·链表
yaoh.wang2 小时前
力扣(LeetCode) 83: 删除排序链表中的重复元素 - 解法思路
程序人生·算法·leetcode·链表·面试·职场和发展
阿昭L2 小时前
leetcode旋转链表
算法·leetcode·链表
山楂树の2 小时前
有效的括号(栈)
数据结构·算法
im_AMBER2 小时前
Leetcode 81 【滑动窗口(定长)】
数据结构·笔记·学习·算法·leetcode
xu_yule2 小时前
算法基础(背包问题)-完全背包
c++·算法·动态规划·完全背包
x976662 小时前
使用 HMAC-SHA256算法对MCU UID进行加密
单片机·嵌入式硬件·算法
gfdhy2 小时前
【c++】素数详解:概念、定义及高效实现(判断方法 + 筛法)
开发语言·c++·算法·数学建模·ai编程
Swift社区2 小时前
LeetCode 452 - 用最少数量的箭引爆气球
算法·leetcode·职场和发展