1. 开散列(哈希桶)概念

开散列法又叫链地址法(开链法),首先对关键码集合散列函数计算散列地址,具有相同地址的关键码归于同一子集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链接起来,各链表的头结存储在哈希表中

  • 散列函数计算:地址=关键码/哈希表的容量

开散列比闭散列的优势

  • 闭散列的思想:找"下一个"为空的位置,那么就会相互冲突,如果冲突的多了,效率就低;
  • 开散列的思想:哈希表的挂单链表,就不会相互冲突

框架:


template<class K>
struct Hash
{
};
// 字符串特化
template<>
struct Hash<string>
{
};//节点
template<class T, class V>
struct HashNode
{pair<T, V> _kv;HashNode<T, V>* _next;
};
//哈希表
template<class T, class V>
class HashTable
{typedef HashNode<T, V> Node;
public:bool Erase(const K& key)Node* Find(const K& key)bool Insert(const pair<K, V>& kv)
private:vector<Node*> _tables;size_t _n = 0;
};

2.把各种类型转化为整形以及字符串的特化

template<class K>
struct Hash
{size_t operator()(const K& key){return key;}
};
// 特化
template<>
struct Hash<string>
{size_t operator()(const string& s){size_t value = 0;for (auto e : s){// BKDR,减少哈希冲突//防止一个桶挂的太长value *= 31;value += e;}return value;}
};

3.查询接口函数

Node* Find(const K& key){//数组为空返回空if (_tables.empty()){return nullptr;}//仿函数:把key转化为整形HashFunc hf;size_t index = hf(key) % _tables.size();//找在第几个桶Node* cur = _tables[index];while (cur){if (cur->_kv.first == key){return cur;}else{cur = cur->_next;}}return nullptr;}

4.插入接口函数

bool Insert(const pair<K, V>& kv){//已经之歌元素有插入失败Node* ret = Find(kv.first);if (ret)return false;HashFunc hf;// 负载因子 == 1时扩容if (_n == _tables.size()){size_t newSize = _tables.size() == 0 ? 10 : _tables.size() * 2;vector<Node*> newTables;newTables.resize(newSize);for (size_t i = 0; i < _tables.size(); ++i){//每个桶的头,如果为空就下一个桶Node* cur = _tables[i];while (cur){//保存一下下一个元素以免找不到Node* next = cur->_next;size_t index = hf(cur->_kv.first) % newTables.size();// 头插,插入顺序不影响cur->_next = newTables[index];newTables[index] = cur;cur = next;}_tables[i] = nullptr;}_tables.swap(newTables);}size_t index = hf(kv.first) % _tables.size();Node* newnode = new Node(kv);// 头插newnode->_next = _tables[index];_tables[index] = newnode;++_n;return true;}

5.删除接口函数

bool Erase(const K& key){//数组为空没有删除的元素if (_tables.empty()){return false;}HashFunc hf;size_t index = hf(key) % _tables.size();//单链表删除保存前一个和后一个Node* prev = nullptr;Node* cur = _tables[index];while (cur){if (cur->_kv.first == key){if (prev == nullptr) // 头删{_tables[index] = cur->_next;}else // 中间删除{prev->_next = cur->_next;}--_n;delete cur;return true;}else{prev = cur;cur = cur->_next;}}return false;}

【C++哈希桶(开散列)】相关推荐

  1. c++哈希(哈希表开散列实现)

    文章目录 0. 前言 1. 开散列 1.1 开散列概念 2. 开散列的代码实现 2.0 定义 2.1 插入实现--Insert 2.2 查找实现--Find 2.3 删除实现--Erase 2.4 仿 ...

  2. 哈希之开散列,闭散列

    先从数据查找开始说起吧,在线性结构,树形结构当中查找一个元素必须经过多次和一些元素进行比较,然后通过比较,查找到对应元素,这种方法多多少少,时间复杂度都是比较高的. 有没有一种方法时间复杂度,仅仅O( ...

  3. C++泛型编程实现哈希表(开散列法)

    代码如下: #include <iostream> #include <vector> using namespace std;template<typename K&g ...

  4. 哈希 ---《哈希函数》------除数的选取为什么是质数?、《哈希冲突》------解决方法、《闭散列》、《开散列》

    一.哈希概念 顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较**.顺序查找时间复杂度为O(N),平衡树中为树的高度,即O(logN ) ...

  5. 哈希(Hash) - 开散列/闭散列

    文章目录: 认识哈希 哈希函数 处理冲突的方法 闭散列(开放定址法) 开散列(链地址法) 哈希表闭散列实现 闭散列基本框架 哈希表闭散列插入(insert) 哈希表闭散列删除(erase) 哈希表闭散 ...

  6. C++---哈希闭散列与开散列

    产生原因 在顺序结构或树形结构的数据集合中,我们想要查询一个元素时,必须进行遍历,所以顺序结构的查询时间复杂度为O(N),树形结构查询的时间复杂度为O(log2^N),但是我们想要一种不用遍历就知道其 ...

  7. 【C++】哈希——unordered系列容器|哈希冲突|闭散列|开散列

    文章目录 一.unordered系列关联式容器 二.哈希概念 三.哈希冲突 四.哈希函数 五.解决哈希冲突 1.闭散列--开放定址法 2.代码实现 3.开散列--开链法 4.代码实现 六.结语 一.u ...

  8. 哈希(散列):(四)C语言实现 哈希 开散列法

    哈希(散列)的概念: https://blog.csdn.net/mowen_mowen/article/details/82943192 C语言实现:静态哈希表: https://blog.csdn ...

  9. 哈希---闭散列和开散列

    闭散列法和开散列法解决哈希冲突 闭散列: 也叫开放定址法,当发生哈希冲突时,寻找合适的空位置 找空位置的方法: 线性探测法 从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止 线性探测优点 ...

最新文章

  1. Android中的dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()
  2. Java语言描述 猴子吃桃问题(递归和循环写法)
  3. android socket 服务端,Android socket 服务端
  4. Vultr 修改 Root 密码
  5. excel VB代码
  6. 解决Chrome浏览器中使用showModalDialog返回值为undefined
  7. 用了这么久的 Chrome,你不会还没掌握这个功能吧?
  8. memcached群集
  9. Python sys.argv[]详解
  10. 电阻的快速选型对开发项目非常重要
  11. php新年倒计时源码,新年倒计时源码
  12. QT 自定义UI控件自适应窗口大小
  13. mongodb数据库
  14. 星巴克咖啡教室活动体验如何?
  15. java拼图_java拼图
  16. Scala编程学习之三-运算符篇
  17. rm——删除文件、文件夹
  18. 单片机系统不稳定情况
  19. 关于kali Linux缺少pyrit或者pyrit无法定位的问题
  20. 转战物联网·基础篇12-了解物联网之物连接相关通信技术(1)

热门文章

  1. AWS云服务学习资料(部分上传至GitHub)
  2. Node.js搭建https服务器
  3. Android开发人员不得不收集的代码,分享一点面试小经验
  4. STM32项目设计:基于stm32的智能家居系统设计
  5. iOS-利用UIBezierPath和CAAnimation制作路径动画
  6. CSV文件如何用EXCEL打开
  7. java文件上传以及上传至FastDFS
  8. VulnStack靶场二
  9. Laya Air - 如何在Laya3D中实现屏幕后期特效?
  10. netty自定义url过滤器抛引用异常