欧意交易所资讯

uncategorized
首页 > 欧意交易所资讯 > 正文内容

哈希表(Hashtable)

2年前 (2024-07-05)欧意交易所资讯

哈希表是普通数组概念的推广,是能够根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数(Hash Function),存放记录的数组叫做散列表(Hash Table)。

在平均情况下,在哈希表中查找一个元素的期望时间是 O(1)O(1) ,因此效率极高。Python中的字典就是采用了哈希表的结构。

1. 直接寻址表

当关键字的全域 UU 比较小时,直接寻址简单有效,假设某应用要用到一个动态集合,其中每个元素都有一个取自于全域 U={0,1,..,m−1}U=\left\{ 0,1,..,m-1 \right\} 的关键字,且假设没有两个元素具有相同的关键字。

我们用数组(直接寻址表) T[0,...,m−1]T[0,...,m-1] 来表示该动态集合,其中每个位置对应全域 UU 中的一个关键字即可。

这样检索、插入和删除操作都是 O(1)O(1) 的时间。

但是如果全域 UU 很大,那么一台计算机的内容是无法存储的;如果实际要存储的关键字集合 K≪UK\ll U ,那么分配给 TT 的大部分空间都要浪费掉。因此我们产生了Hash Table

2. 哈希表

在直接寻址方式下,具有关键字 kk 的元素被存放在槽 kk 中,在散列方式下,利用散列函数 h(k)h(k) 根据关键字 kk 计算出槽的位置,函数 hh 将关键字全域 UU 映射到散列表 T[0,...,m−1]T[0,...,m-1] 的槽位上:

h:U→{0,...,m−1}h:U\rightarrow \left\{ 0,...,m-1 \right\}

这样就能够缩小需要处理的下标范围,即值域从 |U||U| 降到了 mm

但这样存在一个问题,两个关键字可能映射到同一个槽上,称之为碰撞(collision)

,我们通过两种方法来进行解决。一个是链接法(chaining),另一个是开放寻址法(open addressing).

2.1 链接法(chaining)解决碰撞问题

在链接法中,把散列到同一槽中的所有元素放到一个链表中,槽 jj 中有一个指针,指向由所有散列到 jj 的元素构成的链表的头;如果不存在这样的元素,则置为NULL。

如果散列表中的槽树至少与表中的元素数成正比,即 n=O(m)n=O(m) ,则平均来说,查找操作需要常数量的时间;同时,插入操作在最坏情况下需要 O(1)O(1) 的时间,删除操作最坏情况下需要 O(1)O(1) 的时间,因此全部的字典操作平均情况下都可以在 O(1)O(1) 时间内完成。

其优点主要包括:

拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;在用拉链法构造的散列表中,删除结点的操作易于实现

缺点:

在对链表进行存储空间分配的时候,会降低整个程序的运行速率,因为哈希冲突后,用链表去延展来解决。

针对链表进行延展而效率低下的问题,出现了开放寻址法(Open addressing)。

2.2 开放寻址法(Open Addressing)解决碰撞问题

在开放寻址法中,所有的元素都存放在散列表中,因此哈希表的每个表项或包含一个元素,或包含NULL,而不像在链表法中,这里没有链表,也没有元素存放在散列表外。

在开放寻址法中,当要插入一个元素时,需要连续的检查(probe)散列表的各项,直到找到一个空槽来放置待插入的关键字为止,检查的顺序并非是 0,1,...,m−10,1,...,m-1 (这样查找时间为 Θ(n)\Theta(n) ),而是依赖于带插入的关键字,因此我们将散列表扩充为:

h:U×{0,...,m−1}→{0,...,m−1}h:U \times \left\{ 0,...,m-1 \right\} \rightarrow \left\{ 0,...,m-1 \right\}

对开放寻址法来说,要求对每一个关键字 kk ,probe序列为:

<h(k,0),h(k,1),h(k,2)...,h(k,m−1)><h(k,0),h(k,1),h(k,2)...,h(k,m-1)>

插入算法如下所示,即找到probe序列中第一个为空的表项插入。

def hash_insert(T,k): i = 0 if i < m: j = h(k,i) if T[j] == None://找到probe序列中第一个为空的表项插入 T[j] = k return j i += 1 error "hash table overflow"

查找算法与插入算法类似,在查找过程中,如果找到就返回;如果找到NULL,就查找失败。

def hash_search(T,k): i = 0 if i < m: j = h(k,i) if T[j] == k: return j if T[j] == None: return None i += 1 return None

在开放寻址中,删除操作执行较为困难,如果从槽 ii 中删除关键字,不能仅仅将表项置为NULL,这样的话,如果在插入某关键字 kk 的probe过程中,发现 ii 被占用了,则 kk 被插到后面的位置。当从槽 ii 中删除关键字后,则无法检索关键字 kk 。因此需要额外的机制,将删除的表项设置为DELETED,并且需要修改插入和查找算法。

但是如果使用了DELETED,查找时间就不再依赖于装载因子了,因此在必须删除关键字的应用中,往往采用链接法来解决碰撞。

常见的probe方法包括:

线性probe二次probe双重probe

这里不做详细介绍。

3. 链接法哈希表代码实现

以下是采用链接法实现的哈希表,主要用了List来存放链表,并且为了提高检索速度实现了resize方法。

#coding=utf-8 class MyHash(object): 哈希表设计 def __init__(self,length=10): self.length = length self.slots = [[] for i in range(self.length)] self.datasize = 0 def hash(self,k): return k % self.length def add(self,k,v): 添加(k,v) if self.datasize >= len(self.slots): self.resize() index = self.hash(k) if self.slots[index] != []: # 先判断是否有内容在里面 # 在判断是否有key重复 for item in self.slots[index]: if k == item[0]: self.slots[index].remove(item) #然后加入 self.slots[index].append((k,v)) self.datasize += 1 def get(self,k): 查找 index = self.hash(k) if self.slots[index] != []: for item in self.slots[index]: if k == item[0]: return item[1] raise KeyError def resize(self): 当元素过多时,需要将slots的数量增加 self.length *= 2 new_slots = [[] for i in range(self.length)] for slot in self.slots: for item in slot: # print item index = self.hash(item[0]) new_slots[index].append(item) self.slots = new_slots def __len__(self): return len(self.slots) def __str__(self): 当采用print方法时,可以输出想要的内容 return str(self.slots) if __name__ == __main__: h = MyHash() for i in range(23): h.add(i,i+1) print h.get(1) print h print len(h) print h.datasize

扫描二维码推送至手机访问。

版权声明:本文由欧意交易所app官方下载发布,如需转载请注明出处。

转载请注明出处http://doumiduoduo.cn/post/1290.html

相关文章

2023年花1050元拯救一张掉入哥布林巢穴的显卡当61岁张凯丽和55岁周涛站在一起,我才明白什么叫气质和骨相

2023年花1050元拯救一张掉入哥布林巢穴的显卡当61岁张凯丽和55岁周涛站在一起,我才明白什么叫气质和骨相

作者:关注我一下吧 在文章的一开始在开头我想放一下拼多多的显卡链接来着,后来一看链接不正规,那我就不放了,毕竟他是一张最根知底的二手矿卡,也就是说深陷挖矿潮的显卡。以前都在高功率的高...

sol币下一个牛市价格预测,2024年要囤的低估币

随着加密货币市场的波动,Solana(SOL)备受投资者关注。在经历了大幅波动后,SOL在下一轮牛市中将迎来哪些机遇和挑战?本文将深度解析SOL的潜力,为投资者提供有价值的预测和建议。Solana,S...

数字货币市场的传奇:OKX 交易所,投资者的心跳之旅

在数字货币市场,OKX交易所如同繁华熙攘的集市,每天都上演着新的传奇故事。作为一名热衷于区块链技术的投资者,我决定投身这风云变幻的地带,探寻这片数字海洋的瑰宝。 初探OKX:心跳加速的体验 初次接触O...

电脑周边 篇五十六:比台式机小40倍,比笔记本又少了屏幕!实测铭凡UM790PRO迷你主机到底好不好用清华学霸王丽红,不顾劝阻为爱远嫁非洲,再见时昔日同学已认不出

电脑周边 篇五十六:比台式机小40倍,比笔记本又少了屏幕!实测铭凡UM790PRO迷你主机到底好不好用清华学霸王丽红,不顾劝阻为爱远嫁非洲,再见时昔日同学已认不出

作者:科技大怪咖 不知道大家发现了没有?今年的电脑DIY装机市场变得很冷清,如果说前几年是因为人为“挖矿”搞的大家都买不起天价矿卡的话,那今年属实不应该,显卡的价格也下来了,不仅如此...

欧易 app 旧版升级日志及选择欧易数字货币交易所的关键因素

欧易 app 旧版升级日志及选择欧易数字货币交易所的关键因素

(1)2022年6月13日欧易版本6.042升级日志 1.MetaX现已更名为OUYX钱包。 2.欧意 3、欧易X钱包现支持查询币种价格、变动及走势。 在选择欧币数字货币交易所时,我们应该注意欧币:...

全新界面设计与功能优化升级,提升交易效率与资产安全

全新界面设计 界面设计既简洁又充满现代感,操作区域布局得当。在资产页面,我能迅速浏览到各种资产的最新情况,而在交易页面,委托下单等操作简便易行,整体使用体验变得更加顺畅高效,视觉效果也显著提升。 色彩...

欧意交易平台 v67.72.1 2024 官方安卓版

欧意交易所app是一款专业的比特币交易平台,还支持莱特币、以太币等数字货币,提供及时丰富的行业资讯,支持多种币种在线交易,专业分析师在线直播提供精准的指导意见,帮助用户把握投资时机,全球排名第一的虚拟货币交易所已全新升级,提供多种加密货币在线交易,种类丰富,在线交易流程简单,金融级加密技术,使用起来绝对安全!目标是向区块链技术爱好者提供更多的区块链比特币相关的资讯及优质内容。