【 python 学习笔记 -- 数据结构与算法 】哈希表 Implementation of a Hash Table

Python内建的字典就是用 hash table实现的。这里我们只是通过实现自己的hash table来加深对hash table 和hash functions的理解。

【 概念1: Mapping (映射)】

  字典通过键(Key)来索引。一个key对应一个存储的value。任意不可变的数据类型均可作为key。

【 概念2:Hash Table (哈希表)】

  Hash Table根据key直接访问在内存存储位置的数据结构,因而加快了查找速度 (O(1))。

  下图是一个size为11的空的Hash Table, 每一个元素初始化为None:

  

【 概念3: Hash function (散列函数) 】

  key对应的value存放在f(key)的存储位置上,这个对应关系f就叫做Hash Function:

  构造Hash Function的方法有很多:

    例如  (1) Remainder Method (除留余数法):

      假设我们有一个空的Hash Table, 它的size (表长)为11, 现在我们要在Hash Table 中存放一系列整数key: 54, 26, 93, 17, 77, 31;则 remainder hash function 为 h(key)=key%11。

      结果如下:

      

      现在我们的hash table变成:

      

      【概念4: load factor (载荷因子) 】λ=number_of_keys/table_size. 在上述例子中,我们存放了6个items, hash table的长度为11, 则其对应的载荷因子为6/11。

      当我们想要查找一个key的时候,我们只需要利用hash function算出相应的存储位置(slot name) ,查看该位置是否存储了key。这一搜索操作时间复杂性为O(1)。

      【概念5: collision or clash (冲突) 】:两个items可能对应同一个hash function地址,这种情况称为冲突。 例如当我们采用remainder hash function时, 44%11 和77%11都等于0。

                        这种情况下需要选另外的hash function, 或对冲突结果进行处理。

      我们先来介绍其他几种hash function。我们希望能构建一个hash function,使得发生冲突的数量最小化,便于计算,并且在hash table中均匀分布:

      (2)Folding Method (折叠法):

       将关键字(key)分割成位数相同的几部分(最后一部分位数可能不同),然后将这几部分求和,最后再做除留余数法。

       例如:我们的key是一个电话号码4365554601,两个数字为一组(43,65,55,46,01),将这些部分求和43+65+55+46+01=210,最后求余210%11=1。 因此这个电话号码在

          hash table 中存储在slot 1。

      (3)Mid-square Method (平方取中法):

        将关键字取平方后,取其中间的几位数求余作为哈希地址。

        例如: 我们的key是44, 首先取平方44^2=1936, 然后取中间的两位数字93,再取余数93%11=5即为其哈希地址。

      

       对于非整数的key,例如string(字符串),我们可以利用其ordinal values来计算:

       例如 字符串‘cat‘, ord(‘c‘)=99, ord(‘a‘)=97, ord(‘t‘)=116, 所以对应的哈希地址可以是(99+97+116)%11 =4

接下来,我们讨论【冲突处理】的方法:

  (1) open addressing (开放定址法): 当发生冲突时,我们在hash table中查找下一个空的位置来存放发生冲突的key。这里介绍两种寻找的方式:

    (i) Linear Probing (线性探测): 相当于逐个探测hash table,直到查找到一个空的slot,把key存放在该位置。例如,发生冲突的hash value是h, 后面查找的顺序为h+1, h+2, h+3...

     为了防止聚集(clustering),可采用 skip slots的方法。

     (ii) Quadratic Probing (平方探测): 即,发生冲突的hash value是h,则下一个查找的位置为h+1, 再后面的为h+4,h+9,h+16...

 (2)chaining (链表法):将hash value相同的所有元素保存在一个链表中。但发生同一个位置链接的元素越多,搜索难度越大。链表的示意图如下:

    

最后,我们来实现自己的Hash Table, 另其包含以下几种methods:

  HashTable(size): 建立一个新的,空的映射。它返回一个空的映射集合,初始化表长为size

  put(key,val):向表中添加一对新的key-value。如果表中已经存在这个key,则更新这个key对应的value。

  get(key): 给定一个key,返回其对应的value。如果表中不存在这个key则返回None

  del : 通过使用 del map[key] 删除对应的key-value。

  len(): 返回表中存放的key-value对的数量

  in: 使用key in map判断key是否在map中,在则返回True,不在则返回False

  

原文地址:https://www.cnblogs.com/jade-91/p/8319901.html

时间: 2024-10-26 09:01:58

【 python 学习笔记 -- 数据结构与算法 】哈希表 Implementation of a Hash Table的相关文章

Python学习笔记——数据结构和算法(一)

1.解压序列赋值给多个变量 任何的序列(或者是可迭代对象)可以通过一个简单的赋值语句解压并赋值给多个变量. 唯一的前提就是变量的数量必须跟序列元素的数量是一样的. >>> data = [ 'ACME', 50, 91.1, (2012, 12, 21) ]>>> name, shares, price, date = data >>> name, shares, price, (year, mon, day) = data >>>

【 python 学习笔记 -- 数据结构与算法 】冒泡排序 Bubble sort

推荐一个可视化的网站 [ Visual Algo ]: URL= 'https://visualgo.net/en/sorting' 这个网站给出了各种排序算法的原理和过程,通过动态形式直观得展现出来.另外还给出了相关的pseudo-code,以及具体执行到code的哪一步. [冒泡排序] 需要重复地走访需要排序的数列.走访过程中比较相邻两个items的大小,如果顺序不对,则交换两个items. 因此,每完成一次走访(pass),需要排序的部分的最大值就会移动到合适的位置. 这个过程看起来就像每

【 python 学习笔记 -- 数据结构与算法 】插入排序 Insertion Sort

[插入排序]:每次保证列表最左端子序列是排好顺序的,然后取下一个元素,扫描其左端的子序列,将其中大于目标元素的元素右移一个位置,直到找到合适的位置将目标元素插入子序列中.逐步增大排序完成的sublist的长度,最终完成整个列表的排序 算法思路如下: 1. 列表最左边第一个元素认为已经排序好了 2. 取下一个元素(目标元素),在它前面已经排序完成的子序列中从后向前扫描 3. 如果子序列中被扫描的当前元素大于目标元素,则将当前元素右移一个位置 4. 重复第3步,直到被扫描的元素小于或等于目标元素 5

【 python 学习笔记 -- 数据结构与算法 】归并排序 Merge Sort

[归并排序]这里我们利用递归算法不断地将列表一分为二,base case就是列表中没有元素或者只剩一个元素,因为此时这个子列表必然是正序的:然后再逐步把两个排序完成的子列表合并成一个新的正序列表,直到所有元素排序完毕. [示意图]这是一个从下至上的过程(Bottom-Up) 将列表不断从中间分成两个子列表,直到到达最底部,子列表中只有一个元素 然后,从下至上不断合并两个子列表,将两个子列表的所有元素排序形成一个新的列表. [ implementation of merge sort ] 可以利用

[学习笔记]数据结构与算法

1.排序简单排序:?冒泡排序:将n个数从上往下排列,从第0个数开始依次对前n个.前n-1个.前n-2个数进行比较,保持小数在前大数在后,不符合就交换.在这个过程中,最后一个数始终是最大数.?选择排序:对所有n个.后n-1个.后n-2个依次比较,用一个变量存最小数,一趟比较完成之后,将最小数与所比较数据的第一个数进行交换.在这个过程中,第一个数始终是最小数.?插入排序:从第1个数开始向前扫描比较,小则插入.对于未排序数据,在已排序序列中向前扫描,并找到相应的位置插入.在这个过程中,整个序列局部有序

python数据结构与算法——哈希表

哈希表 学习笔记 参考翻译自:<复杂性思考> 及对应的online版本:http://greenteapress.com/complexity/html/thinkcomplexity004.html 使用哈希表可以进行非常快速的查找操作,查找时间为常数,同时不需要元素排列有序 python的内建数据类型:字典,就是用哈希表实现的 为了解释哈希表的工作原理,我们来尝试在不使用字典的情况下实现哈希表结构. 我们需要定义一个包含 键->值 映射 的数据结构,同时实现以下两种操作: add(k

数据结构与算法--------哈希表

1.概述: 数据结构:哈希表 插入时间复杂度:O(1) 删除时间复杂度:O(1) 查找时间复杂度: 优点: 哈希表的操作速度比较快,如插入.删除的时间复杂度都是常量O(1),可以在一秒内查找上千条记录 哈希表的编程实现相对容易 缺点: 哈希表不能被填满.哈希表被基本填满的时候,性能会急剧下降,所以为了保证性能,你一定要确保你哈希表的容量的大小是足够的 哈希表到其他哈希表的数据迁移过程是一个费时的过程(如定期将数据迁移到更大的哈希表中去会很费时).如果一开始没有预估好你的数据量的大小,初始时创建的

Python学习笔记19(算法)

1.二分查找 只能用二分查找查找有序列表 def bin_search(data,val): #data为被查找的列表,val是要查找的值 low = 0 high = len(data) - 1 while low <= high: mid = (low+high)//2 if data[mid] == val: return mid #找到了,返回val所在的索引 elif data[mid] < val: low = mid + 1 else: high = mid - 1 return

python学习笔记之module &amp;&amp; package

个人总结: import module,module就是文件名,导入那个python文件 import package,package就是一个文件夹,导入的文件夹下有一个__init__.py的文件, __init__.py可以有两种形式, 一种是直接import多个模块,例如 import fibo import abc 另外一种是 __all__ = ["A","B"] python学习笔记之module && package python的mo