传统的哈希表

对于长度为n的哈希表,它的存储过程如下:
根据 key 计算出它的哈希值 h=hash(key)
假设箱子的个数为 n,那么这个键值对应该放在第 (h % n) 个箱子中
如果该箱子中已经有了键值对,就使用开放寻址法或者拉链法解决冲突

哈希冲突

如果不同字符串被hash到了同一个位置,称为哈希冲突。解决哈希冲突的常用办法有以下几种:

拉链法(开哈希)

在使用拉链法解决哈希冲突时,对于每一个数组位置,放置的元素相当于一个链表,属于同一个箱子的所有键值对都会排列在链表中。当有冲突时,我们将这个元素插入到链表尾部,以此来避免冲突。

线性探测法(闭哈希)

线性探测法属于开放定址法的一种。

当冲突发生的时候,我们检查冲突的哈希地址的下一位(数组下标加一),判断能否插入,如果不能则再继续检查下一个位置。

在拉链法实现的哈希表中,因为链表的存在,可以弹性地容纳键值对,而对于线性探测法实现的哈希表,其容纳键值对的数量是直接受到数组大小的限制的。所以必须在数组充满以前调整数组的大小。一般来说,每当总键值对的对数达到数组的一半后,我们就将整个数组的大小扩大一倍。

闭哈希用的不多,因为一直往下一位插入会导致越来越多的collision

重哈希

这种方法是同时构造多个不同的哈希函数:

Hi=RH1(key)        i=1,2,…,k

当哈希地址Hi=RH1(key)发生冲突时,再计算Hi=RH2(key)……,直到冲突不再产生。这种方法不易产生聚集,但增加了计算时间。

哈希表的扩容

一般来说,每当总键值对的对数达到数组的一半后,我们就将整个数组的大小扩大一倍。扩容时要把所有的元素重新计算hash并插入到更大容量的新哈希表中。


分布式哈希表

参考DHT,将一张哈希表按hash值分割到不同机器上。


一致性哈希

在普通分布式哈希表中,如果有节点动态加入或者删除,就会导致大量数据失效。那么如何改进这一情况呢?

consistent hashing 是一种 hash 算法,简单的说,在移除 / 添加一个 cache 时,它能够尽可能小的改变已存在 key 映射关系。它的思想是把机器和数据都hash到同一个空间中。

比如在Chord算法里,每台节点负责它顺时针方向到下一个节点之前的这一区域的hash数据点。如果在这一区间内有节点的动态加入/删除,那么只有这一区间端点的两台机器会受影响,而其他机器都不会。

另外还有一种DHT算法叫做Kademlia,它就是P2P下载的基础。可以参考https://colobu.com/2018/03/26/distributed-hash-table/


红黑树

红黑树(Red-black Tree)是一种平衡排序二叉树(Balanced Binary Search Tree),在它上面进行增删查改的平均时间复杂度都是 O(logn),是居家旅行的常备数据结构。

Q: 在面试中考不考呢?
A: 很少考……

Q: 需不需要了解呢?
A: 需要!

Q: 了解到什么程度呢?
A: 知道它是 Balanced Binary Search Tree,知道它支持什么样的操作,会用就行。不需要知道具体的实现原理。

红黑树的几个常用操作

Java当中,红黑树主要是TreeSet,位于java.util.TreeSet,继承自java.util.AbstractSet,它的主要方法有:

  • add,插入一个元素。
  • remove,删除一个元素。
  • clear,删除所有元素。
  • contains,查找是否包含某元素。
  • isEmpty,是否空树。
  • size,返回元素个数。
  • iterator,返回迭代器。
  • clone,对整棵树进行浅拷贝,即不拷贝元素本身。
  • first,返回最前元素。
  • last,返回最末元素。
  • floor,返回不大于给定元素的最大元素。
  • ceiling,返回不小于给定元素的最小元素。
  • pollFirst,删除并返回首元素。
  • pollLast,删除并返回末元素。

更具体的细节,请参考Java Reference

此外,在Java当中,有一种map,用红黑树实现key查找,这种结构叫做TreeMap。如果你需要一种map,并且它的key是有序的,那么强烈推荐TreeMap

在C++当中,红黑树即是默认的setmap,其元素也是有序的。
而通过哈系表实现的则分别是unordered_setunordered_map,注意这两种结构是在C++11才有的。
在Python当中,默认的set和dict是用哈系表实现,没有默认的红黑树。如果你想使用红黑树的话,可以使用rbtree这个模块,下载地址:https://pypi.python.org/pypi/rbtree/0.9.0


Ref:https://xiekeyi98.com/819591f7.html

Leetcode Lect7 哈希表的更多相关文章

  1. 【LeetCode】哈希表 hash_table(共88题)

    [1]Two Sum (2018年11月9日,k-sum专题,算法群衍生题) 给了一个数组 nums, 和一个 target 数字,要求返回一个下标的 pair, 使得这两个元素相加等于 target ...

  2. 【LeetCode 36_哈希表】Valid Sudoku

    //occupyed_1检查行是否占用 //occupyed_2检查列是否占用 //occupyed_3检查块是否占用 bool isValidSudoku(vector<vector<c ...

  3. [LeetCode] #1# Two Sum : 数组/哈希表/二分查找/双指针

    一. 题目 1. Two SumTotal Accepted: 241484 Total Submissions: 1005339 Difficulty: Easy Given an array of ...

  4. 拼写单词[哈希表]----leetcode周赛150_1001

    题目描述: 给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars. 假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我 ...

  5. LeetCode刷题总结-哈希表篇

    本文总结在LeetCode上有关哈希表的算法题,推荐刷题总数为12题.具体考察的知识点如下图: 1.数学问题 题号:149. 直线上最多的点数,难度困难 题号:554. 砖墙,难度中等(最大最小边界问 ...

  6. 重复的DNA序列[哈希表] LeetCode.187

    所有 DNA 由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:"ACGAATTCCG".在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助. 编写一个函数 ...

  7. C#LeetCode刷题-哈希表

    哈希表篇 # 题名 刷题 通过率 难度 1 两数之和 C#LeetCode刷题之#1-两数之和(Two Sum) 42.8% 简单 3 无重复字符的最长子串   24.2% 中等 18 四数之和   ...

  8. leetcode 刷题(数组篇)1题 两数之和(哈希表)

    题目描述 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标. 你可以假设每种输入只会对应一个答案.但是,数组中同一个元 ...

  9. LeetCode通关:哈希表六连,这个还真有点简单

    精品刷题路线参考: https://github.com/youngyangyang04/leetcode-master https://github.com/chefyuan/algorithm-b ...

随机推荐

  1. os模块、sys模块、json模块、pickle模块、logging模块

    目录 os模块 sys模块 json模块 pickle模块 logging模块 os模块 功能:与操作系统交互,可以操作文件 一.对文件操作 判断是否为文件 os.path.isfile(r'路径') ...

  2. C文件 CMakeList.txt编译器配置错误的问题 error:invalid conversion from 'int' to 'LAYER_TYPE' [-fpermissive]....

    在编译C工程时,遇到了如下错误: 一般看到类型错误,主要考虑是不是编译器错了. 以下引用:https://www.cnblogs.com/liushui-sky/p/7729838.html 后缀为. ...

  3. Linux分屏操作

    需要安装工具tmux (1)安装工具 在ubuntu系统中使用sudo apt-get install tmux安装tmux工具 (2)使用工具 1,输入命令tmux使用工具 2,上下分屏:ctrl ...

  4. Java——容器(Auto-boxing/unboxing)

    [打包/解包] 在Map中需要增加一个数值时,需要new一个对象出来,输出后又得进行强制类型转换,这就造成不便.在JDK1.5中使用Map接口提供了一种新的机制.   在合适的时机自动打包/解包(在J ...

  5. 10分钟学会React Context API

    Create-react-app来学习这个功能: 注意下面代码红色的即可,非常简单. 在小项目里Context API完全可以替换掉react-redux. 修改app.js import React ...

  6. 特征提取算法(4)——LoG特征提取算法

    目录 1.介绍 2.LoG原理 3.数学原理 4.模板性质 1.介绍 LoG(DoG是一阶边缘提取)是二阶拉普拉斯-高斯边缘提取算法,先高斯滤波然后拉普拉斯边缘提取. Laplace算子对通过图像进行 ...

  7. All-one Matrices

    All-one Matrices 单调栈 最大全一矩阵计数 #include<bits/stdc++.h> #define maxn 3005 using namespace std; # ...

  8. 关于MonoBehaviour的单例通用规则

    长久以来,对于基于MonoBehaviour的单例总是心有梗结,总觉得用得很忐忑,今天,终于有时间思考和总结了下,理清了想通了.代码和注释如下: 其中GameLogic是我们自己的控制游戏生命周期的管 ...

  9. Python编程:从入门到实践—函数

    从函数中修改列表 一家为用户提交的设计制作3D打印模型的公司,需要打印的设计存储在一个列表中,打印后移到另一个列表中. #!/usr/bin/env python # -*- coding:utf-8 ...

  10. qbzt day6 下午 模拟赛

    我太菜了 T2 给定一张有向图,每个点有点权.试找到一条路径,使得该路径上的点权最 大值减去点权最小值最大,问这个差最大是多少.   话说这个题第一个想到的思路是tarjan缩点+拓扑排序来着... ...