Hash表简介

基本思想

哈希存储的基本思想是根据当前待存储数据的特征,以记录关键字(key)为自变量,设计一个哈希函数Hash,根据Hash计算出对应的函数值Hash(key),以这个值(哈希地址)作为数据元素的地址,并将数据元素存入到相应地址的存储单元中。按照这个思想构造的表就叫做哈希表(Hash table,也叫散列表)

查找时再根据要查找的关键字key采用同样的函数计算出哈希地址,然后根据Hash(key)直接到相应的存储单元中去取要找的数据元素即可。

建立步骤

step 1:取数据元素的关键字key,计算其哈希函数值(地址)。若该地址对应的存储空间还没有被占用,则将该元素存入;否则执行step2解决冲突。

step 2:根据选择的冲突处理方法,计算关键字key的下一个存储地址。若下一个存储地址仍被占用,则继续执行step 2,直到找到能用的存储地址为止。

问题

对于n个数据元素的集合,总能找到关键字与存放地址一一对应的函数。假设最大关键字为m,可以分配m个数据元素存放单元,选取函数Hash(key)=key即可,但是这样会造成存储空间的很大浪费,甚至不可能分配这么大的存储空间。通常关键字的集合比哈希地址集合大得多(tips:这里的大不是说个数,而是总体所用空间),因而经过哈希函数变换后,可能将不同的关键字映射到同一个哈希地址上,这种现象称为冲突(Collision)。映射到同一哈希地址上的关键字称为同义词。可以说,冲突不可能避免,只能尽可能减少。

Hash表实现

通过文章前面的了解我们可以知道,具体去实现Hash表需要我们完成:1)Hash函数构造;2)制定解决冲突的方案。

Hash函数构造

构造哈希函数的方法有很多,总的原则是尽可能简单,以便提高转换速度,且要尽可能将关键字集合空间均匀的映射到地址集合空间中,同时尽可能降低冲突发生的概率。

下面是一些常用的哈希函数构造方法:

  1. 直接地址法

    					Hash(key) = a*key + b(a、b为常数)
  2. 除数留余法

    					H(key) = key % p  (p ≤ m)

    取关键字除以p的余数作为哈希地址,p最好选择一个小于或等于m(哈希地址集合的个数)的某个最大素数,也可以是不包含小于20质因子的合数。

    					哈希表长度	8	16	32	64	128	256	512
    最大素数 7 13 31 61 127 251 503
  3. 数字分析法

    设关键字集合中,每个关键字均由m位组成,每位上可能有r中不同的符号。数字分析法根据r种不同符号及在各位上的分布情况,选取某几位,组合成哈希地址。所选的位应是各种符号在该位上出现的概率大致相同。

  4. 平方取中法

    对关键字平方后,按哈希表大小,取中间的若干位作为哈希地址。

  5. 折叠法(Folding)

    比如key=135790,要求Hash(key)是2位数的散列值。那么我们将key变为13+57+90=160,然后去掉高位“1”,此时Hash(key)=60,这就是他们的哈希关系,这样做的目的就是地址与每一位的key都相关,来做到“散列地址”尽可能分散的目地。

冲突处理方法

影响哈希查找效率的一个重要因素是哈希函数本身。当两个不同的数据元素的哈希值相同时,就会发生冲突。为减少发生冲突的可能性,哈希函数应该将数据尽可能分散地映射到哈希表的每一个表项中。

解决冲突的方法有以下两种:

  1. 开放地址法

    所谓开放定址法,即由关键字得到的哈希地址一旦产生了冲突,也就是说,该地址已经存放了数据元素。我们需要寻找下一个空的哈希地址,只要哈希表足够大,空的哈希地址总能找到,并将数据元素存入。常用的找空哈希地址方法有下列三种。

    (1)线性探测法

    						Hi=(Hash(key)+di)%m(1=<i<m)

    其中,Hash(key)为哈希函数,m为哈希表长度,di为增量序列1,2…,m-1,i为探测次数。

    (2)二次探测法

    地址增量序列为:di=12,−12,22,−22,...,q2,−q2(q≤m/2)d_i = 1^2, -1^2,2^2,-2^2 ,...,q^2,-q^2 (q ≤ m/2)di​=12,−12,22,−22,...,q2,−q2(q≤m/2)

    (3)双哈希函数探测法

    				Hi =( H(key) + i * RH(key) )%m ( i = 1,2,3,..., m-1 )

    H(Key) , RH(Key) 是两个哈希函数,m为哈希表长度。

    先用第一个哈希函数对关键字计算哈希地址,一旦产生地址冲突,再用第二个函数确定移动的步长因子,最后通过步长因子序列由探测函数寻找空余的哈希地址。

    		H1 = ( a+b )%m , H2 = ( a + 2b )%m , ... , Hm-1 = ( a+(m-1)*b )%m
  2. 链地址法

    将哈希值相同的数据元素存放在一个链表中,在查找哈希表的过程中,当查找到这个链表时,必须采用线性查找方法。

leetcode两数之和python实现

题目描述

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1]

基于Hash思想的实现

class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
Hash_dict = {}
for i in range(len(nums)):
Hash_dict[nums[i]] = i
for i in range(len(nums)):
temp = target - nums[i]
if temp in Hash_dict & i != Hash_dict[temp]:
return [i,Hash_dict[temp]]

【数据结构】Hash表简介及leetcode两数之和python实现的更多相关文章

  1. leetcode 两数之和 python

      两数之和     给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 1 ...

  2. LeetCode两数之和-Python<一>

    下一篇:LeetCode链表相加-Python<二> 题目:https://leetcode-cn.com/problems/two-sum/description/ 给定一个整数数组和一 ...

  3. LeetCode两数之和

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

  4. leetcode - 两数之和Ⅳ 输入BST(653)

    题目描述:给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true. 解题思路:根据二叉搜索树的特点,对二叉搜索树进行中序遍历可以得到一个从小到达排 ...

  5. Leetcode -- 两数之和Ⅰ

    1. 两数之和 题目描述:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标. 示例:给定 nums = [2, 7, 11, 15 ...

  6. leetcode两数之和go语言

    两数之和(Go语言) 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复 ...

  7. Leetcode 两数之和 (散列表)

    给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...

  8. leetcode 两数之和 II - 输入有序数组

    给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2. 说明: 返回的下标值 ...

  9. leetcode NO.1 两数之和 (python实现)

    来源 https://leetcode-cn.com/problems/two-sum/description/ 题目描述 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个 ...

随机推荐

  1. 049、Java中使用switch判断,不加入break时的操作

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  2. UVA - 1423 Guess (拓扑排序)

    题意:已知矩阵S,求序列a.已知矩阵Sij = “ + ” if ai + . . . + aj > 0; Sij = “ − ” if ai + . . . + aj < 0; and ...

  3. IOCTL_DISK_GET_DRIVE_GEOMETRY

    IOCTL_DISK_GET_DRIVE_GEOMETRY: 获取磁盘参数 c++实现: #include <Windows.h> #include <winioctl.h> ...

  4. vs code 切换语言(切换回英文)

    安装中文 安装教程:https://www.cnblogs.com/chenxi188/protected/p/11757456.html 切换回英文 调出搜索:ctrl+shift+p 输入:lan ...

  5. django ModelForm在模板中显示中文

    情景再现 修改ModelForm 效果

  6. Elasticsearch 搜索数据

    章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...

  7. Spring Boot Hello World (restful接口)例子

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  8. python --- excel文件处理

    1.安装第三方库:openpyxl 2.操作示例 from openpyxl import load_workbook #.打开文件 file = load_workbook("test.x ...

  9. phi

    给定 \(T\) 个正整数 \(n\) ,对于每个 \(n\) ,输出做小的 \(m\) ,使得 \(\phi (m)\ge n\). 思路1:搞个线性欧拉函数筛,后缀最大值,二分查找 思路2:直接求 ...

  10. ZOJ - 3123 Subsequence (滑动窗口)

    题意:给定N个数,求和大于等于S的最短连续子序列的长度. 分析:滑动窗口即可.两种写法. 1. #include<cstdio> #include<cstring> #incl ...