hashtable初步——一文初探哈希表
在<<STL源码剖析>>中,vector封装了数组的数据结构,list封装了链表的结构,而set和map封装了二叉树的数据结构。那么hashtable,具有怎么的作用呢,其本质又是什么呢?本质就是查找表,既然是查找表,其查找效率自然就是O(1).下面来看看hashtable究竟是什么?


上述对hashtable的描述,表明了这样的观点:hashtable的引入其实就是相当于是一种字典,也就是查找表。当然了在内存空间十分富足的条件下,我们可以有多少元素,分配多大的内存空间,构成一一映射。但是这是不现实的,通常我们 分配的内存空间大小远小于元素个数。

可见我们可以通过hash函数来产生映射关系,这种函数叫做散列函数,那么这种条件下,必然会带来,有些元素被映射到了相同的内存空间,而这个就叫做哈希冲突或者哈希碰撞,如下图表述:

也就是说,只要分配空间小于元素数量,碰撞问题是无法避免的,但是我们可以采用有效策略来提高检索效率,使得存在很多元素时候,这些元素在内存中的分布尽量均衡(减少有些内存单元无元素,有些内存单元元素很多这种不平衡情况)。在STL中,采用的策略是开拉链法(想想拉链的形状,这是很想形象的表述),来领教一下开拉链法

我们来看一下STL中的开拉链法究竟是如何实现的:

也就是,用一个vector存放所有bucket,vector的每一个内存单元存放一个bucket,而这个bucket究竟是什么呢?其本质就是其下面维护的链表的头节点!!!而每个bucket下面的链表,则存放了元素和指向下一个节点的地址。也就是每一个bucket维护一个list。这就是上面书中所说:表格内的每个单元,涵盖的不只是个节点,甚至可能是一桶节点。
我们可以从下图看到更加细节的东西:

这充分说明了:每个节点存放了我们要存放的元素以及指向下一个节点的指针。而bucket是存在于vector中的,而vector具有自动扩容的能力,说明hashtable在某种条件下是会扩容的。
我们来看一下hashtable迭代器具有怎样的性质:

可见,其迭代器指向的是节点,因此我们可以通过hashtable迭代器获得我们想要查找的元素。值得一提的是如果迭代器当前处于list的结尾,那么hash_table_node->指向了下一个桶子。再看看hashtable类型:

其实从上文我们也能看出hashtable迭代器是一个前向迭代器!!!
再来看看hashtable模板参数有哪些:

这里我还没全部理解所有的参数,先跳过这个地方的讲述。我们来看看hashtable的扩容规则:

我们可以看到:vecotor的大小是质数,当需要扩容时候,寻找最接近当前数,并大于当前数,为当前数约两倍的质数
关于插入行为,在hashtable中,有两种插入行为:insert_unique()(显然不能插入重复元素),insert_equal()(可以插入重复元素)。而不管是哪种插入行为,都要先判断插入元素之后,是否要扩容,也就是resize,如果需要,先resize,再insert。
那么什么时候执行resize呢???下图给出了答案:

可见,当所有list节点的总数的大于vector容量时,就要扩容了!
而hashtable具有获取元素所在bucket的功能:

关于hashtable所有的知识这里基本都介绍完毕了,下面我们来看一个例子:




我们先来看看结果:

可见,当我们定义bucket集合vector大小的时候,会找与当前数字最接近的质数,同时每个bucket被初始化为空,同时我们也应该注意到:hashtable并不具备和set和map这样的自动排序功能!它只是按照散列函数的功能,将对应元素放到了对应的位置!
关于扩容

可见,当元素总数量超过vector的size的时候,那么就会产生扩容。
至此介绍完毕!
hashtable初步——一文初探哈希表的更多相关文章
- 集合>哈希表类Hashtable和SortedList排序列表类
集合>哈希表类Hashtable Hashtable一种键值对的集合 ,哈希表内部的排列是无序的,而且哈希表没有提供排序方法. 集合>哈希表类Hashtable>构造普通哈希表 代码 ...
- Java中哈希表(Hashtable)是如何实现的
Java中哈希表(Hashtable)是如何实现的 Hashtable中有一个内部类Entry,用来保存单元数据,我们用来构建哈希表的每一个数据是Entry的一个实例.假设我们保存下面一组数据,第一列 ...
- 哈希表(Hash Table)原理及其实现
原理 介绍 哈希表(Hash table,也叫散列表), 是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映 ...
- 深入理解PHP内核(六)哈希表以及PHP的哈希表实现
原文链接:http://www.orlion.ga/241/ 一.哈希表(HashTable) 大部分动态语言的实现中都使用了哈希表,哈希表是一种通过哈希函数,将特定的键映射到特定值得一种数据 结构, ...
- 简单的哈希表实现 C语言
简单的哈希表实现 简单的哈希表实现 原理 哈希表和节点数据结构的定义 初始化和释放哈希表 哈希散列算法 辅助函数strDup 哈希表的插入和修改 哈希表中查找 哈希表元素的移除 哈希表打印 测试一下 ...
- Java知多少(79)哈希表及其应用
哈希表也称为散列表,是用来存储群体对象的集合类结构. 什么是哈希表 数组和向量都可以存储对象,但对象的存储位置是随机的,也就是说对象本身与其存储位置之间没有必然的联系.当要查找一个对象时,只能以某种顺 ...
- php扩展开发-哈希表
什么是哈希表呢?哈希表在数据结构中也叫散列表.是根据键名经过hash函数计算后,映射到表中的一个位置,来直接访问记录,加快了访问速度.在理想情况下,哈希表的操作时间复杂度为O(1).数据项可以在一个与 ...
- java数据结构----哈希表
1.哈希表:它是一种数据结构,可以提供快速的插入操作和查找操作.如果哈希表中有多少数据项,插入和删除操作只需要接近常量的时间.即O(1)的时间级.在计算机中如果需要一秒内查找上千条记录,通常使用哈希表 ...
- 使用python实现哈希表、字典、集合
哈希表 哈希表(Hash Table, 又称为散列表),是一种线性表的存储结构.哈希表由一个直接寻址表和一个哈希函数组成.哈希函数h(k)将元素关键字k作为自变量,返回元素的存储下标. 简单哈希函数: ...
随机推荐
- 从ArrayList的优化中想到的
在JDK7中ArrayList有一个小的改动,使用延迟加载的思想,默认构造函数不再初始化生成一个大小为10的数组,而是将elementData先赋值为一个共享的空数组. package java.ut ...
- 查漏补缺:socket编程:TCP粘包问题和常用解决方案(上)
1.TCP粘包问题的产生(发送端) 由于TCP协议是基于字节流并且无边界的传输协议,因此很容易产生粘包问题.TCP的粘包可能发生在发送端,也可能发生在接收端.发送端的粘包是TCP协议本身引起的,TCP ...
- python3.4多线程实现同步的四种方式
临界资源即那些一次只能被一个线程访问的资源,典型例子就是打印机,它一次只能被一个程序用来执行打印功能,因为不能多个线程同时操作,而访问这部分资源的代码通常称之为临界区. 1. 锁机制 threadin ...
- JAVA补0--->String.format()的使用
详细地址:http://blog.csdn.net/lonely_fireworks/article/details/7962171/ 标 志 说 明 示 例 结 果 + 为正 ...
- Leetcode 141题 环形链表(Linked List Cycle) Java语言求解
题目描述: 给定一个链表,判断链表中是否有环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 -1,则在该链表中没有环. Map ...
- powershell加KeePass实现,加密服务器密码清单文件
powershell加KeePass实现,加密服务器清单文件 powershell传教士翻译,改写. 2020-02-27 原文: https://www.altaro.com/msp-doj ...
- PHP实现 3des加密解密
<?php /** * 3des加密 */ class Encrypt{ public function pkcs5_pad($text, $blocksize) { $pad = $block ...
- JAVA GC算法详解
生存还是死亡 对象是否需要被垃圾收集器回收主要有两种方式:引用计数法和可达性分析算法 引用计数法 给对象添加一个引用计数器,每当有一个地方引用他的时候,计数器的数值就+1,当引用失效时,计数器就-1: ...
- fsLayuiPlugin数据表格动态转义
数据表格动态转义提供一种更简洁的方式,主要解决前端laytpl模板转义的问题,对于一些简单的,例如:状态展示,我们可以通过前端编写laytpl模板来处理:对于动态的数据,通过这种静态方式是没有办法处理 ...
- html+css+js+Hbuilder开发一款安卓APP,根本不用学Android开发!
我们知道,要做一款安卓APP,咱们得先学安卓开发语言,例如java,前端后端.那么没有这些开发语言基础,咱们怎么做呢?其实现在有比较好的开发方案就是做webAPP,咱们可以用web前端知识构建安卓客户 ...