在<<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初步——一文初探哈希表的更多相关文章

  1. 集合&gt;哈希表类Hashtable和SortedList排序列表类

    集合>哈希表类Hashtable Hashtable一种键值对的集合 ,哈希表内部的排列是无序的,而且哈希表没有提供排序方法. 集合>哈希表类Hashtable>构造普通哈希表 代码 ...

  2. Java中哈希表(Hashtable)是如何实现的

    Java中哈希表(Hashtable)是如何实现的 Hashtable中有一个内部类Entry,用来保存单元数据,我们用来构建哈希表的每一个数据是Entry的一个实例.假设我们保存下面一组数据,第一列 ...

  3. 哈希表(Hash Table)原理及其实现

    原理 介绍 哈希表(Hash table,也叫散列表), 是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映 ...

  4. 深入理解PHP内核(六)哈希表以及PHP的哈希表实现

    原文链接:http://www.orlion.ga/241/ 一.哈希表(HashTable) 大部分动态语言的实现中都使用了哈希表,哈希表是一种通过哈希函数,将特定的键映射到特定值得一种数据 结构, ...

  5. 简单的哈希表实现 C语言

    简单的哈希表实现 简单的哈希表实现 原理 哈希表和节点数据结构的定义 初始化和释放哈希表 哈希散列算法 辅助函数strDup 哈希表的插入和修改 哈希表中查找 哈希表元素的移除 哈希表打印 测试一下 ...

  6. Java知多少(79)哈希表及其应用

    哈希表也称为散列表,是用来存储群体对象的集合类结构. 什么是哈希表 数组和向量都可以存储对象,但对象的存储位置是随机的,也就是说对象本身与其存储位置之间没有必然的联系.当要查找一个对象时,只能以某种顺 ...

  7. php扩展开发-哈希表

    什么是哈希表呢?哈希表在数据结构中也叫散列表.是根据键名经过hash函数计算后,映射到表中的一个位置,来直接访问记录,加快了访问速度.在理想情况下,哈希表的操作时间复杂度为O(1).数据项可以在一个与 ...

  8. java数据结构----哈希表

    1.哈希表:它是一种数据结构,可以提供快速的插入操作和查找操作.如果哈希表中有多少数据项,插入和删除操作只需要接近常量的时间.即O(1)的时间级.在计算机中如果需要一秒内查找上千条记录,通常使用哈希表 ...

  9. 使用python实现哈希表、字典、集合

    哈希表 哈希表(Hash Table, 又称为散列表),是一种线性表的存储结构.哈希表由一个直接寻址表和一个哈希函数组成.哈希函数h(k)将元素关键字k作为自变量,返回元素的存储下标. 简单哈希函数: ...

随机推荐

  1. Linux的date用法

    显示时间是个常用的命令,在写shell脚本中也经常会用到与日期相关文件名或时间显示.无论是linux还是windows下都是date命令. Linux下date命令用法 date [OPTION]… ...

  2. python返回值进行unpack

    最近在写yolov3,因为yolov3的多输出性质,所以我打算写适配多输出的工具函数,在numpy中可以在一个array中包含多个不同维度的array,但在tensorflow中一个tensor只能保 ...

  3. 从赴美IPO绝迹 看那些烧成泡沫的互联网企业

    曾经,赴美上市是很多中国企业的终极梦想.然而在当下,随着中概股在美国股市股价的不断走低.中国赴美上市企业私有化速度的加快,大众才发现,原来美国股市并不是那么好混的.但不管怎样,赴美上市始终是一种荣耀. ...

  4. 【Art】抗疫路上,温暖相伴

    2020年3月. 本应是春暖花开的时节,武汉却是寒冷的,整个中国也是寒冷的. 疫情将人们逼得退无可退,只能待在家里看着电视新闻与手机上一个个数字不断跳动,等待着它们背后前线的无数命悬一线的战士的胜利讯 ...

  5. Hibernate和Mybatis的工作原理以及区别

    一.Mybatis的工作流程图 (1).原理详见: MyBatis应用程序根据XML配置文件创建SqlSessionFactory,SqlSessionFactory在根据配置,配置来源于两个地方,一 ...

  6. springboot配置文件读取pom文件信息

    解决的问题 springboot(当然别的也可以)多环境切换需要该配置文件,打包时不够方便. 解决: 配置文件能读取pom文件中的配置,根据命令选择不同配置注入springboot的配置文件中 pom ...

  7. 不要写很酷但同事看不懂的Java代码

    你好呀,我是沉默王二,一个和黄家驹一样身高,和刘德华一样颜值的程序员.为了提高 Java 编程的技艺,我最近在 GitHub 上学习一些高手编写的代码.下面这一行代码(出自大牛之手)据说可以征服你的朋 ...

  8. electron+vue制作桌面应用--自定义标题栏

    electron会默认显示边框和标题栏,如下图 我们来看一下如何自定义一个更加有(gao)意(da)思(shang)的标题栏,例如网易云音乐这种 首先我们要把默认的标题栏删掉,找到主进程中创建窗体部分 ...

  9. 在浏览器中使用ES6的模块功能 import 及 export

    感谢英文原作者 Jake Archibald 的技术分享 各个浏览器对于ES6模块 import . export的支持情况 Safari 10.1. Chrome 61. Firefox 54 – ...

  10. 基础JavaScript练习(三)总结

    任务目的 实践JavaScript数组.字符串相关操作 任务描述 基于任务四进行升级 将新元素输入框从input改为textarea 允许一次批量输入多个内容,格式可以为数字.中文.英文等,可以通过用 ...