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


一、基本概念

1、直接寻址表

当关键字的全域U比较小时直接寻址是一种简单有效的方法
在这里插入图片描述
但直接寻址表存在以下缺点:
1.当全域U很大时,需要消耗大量内存,很不实际
2.如果全域U很大而实际出现的key很少,则大量空间被浪费
3.无法处理关键字不是数字的情况

2、哈希

直接寻址表:key为k的元素放到k的位置上
改进直接寻址表:哈希(Hashing)

1.构建大小为m的寻址表T
2.key为k的元素放到h(k)位置上
3.h(k)是一个函数,其将全域U映射到表T[0,1,...,m-1]

3、哈希表

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

python中的dict类型就是哈希表的原理,存储方式是key-value,通过键来快速的访问value,字典在访问操作上时间复杂度为O(1)。

通常支持以下操作:

insert(key,value): 插入键值对
get(key): 如果存在建为key的键值对则返回其value,否则返回空
delete(key): 删除键为key的键值对

例:
假设有一个长度为7的哈希表,哈希函数为 h(k)=k%7。元素集合{14,22,3,5}的方式如下图:
在这里插入图片描述
注:常见的哈希函数

h(k)=k%m .
h(k)=floor(m*(Akey%1)) .
ha,b(k)=((a
key + b) mod p) mod m . 其中a,b=1,2,…p-1

4、哈希冲突

由于哈希表的大小是有限的,而要存储的值的总数量是无限的,因此对于任何哈希函数,都会出现两个不同元素映射到同一个位置上的情况,这种情况叫哈希冲突。

比如h(k)=k%7,h(0)=h(7)=h(14)=…=0
在这里插入图片描述

解决哈希冲突:

1、开放寻址法
如果哈希函数返回的位置已经有值,则可以向后探查新的位置来存储这个值

  • 线性探查:如果位置i被占用,则探查i+1,i+2,…
  • 二次探查:如果位置i被占用,则探查i+12,i-12,i+22,i-22,…
  • 二度哈希:有n个哈希函数,当使用第一个哈希函数发生冲突时,则尝试第二个,第三个,…

2、拉链法
哈希表每个位置都连接一个链表,当发生冲突时,冲突的元素将加到该位置链表的最后
在这里插入图片描述


二、代码实现

主要使用拉链法解决哈希冲突

# __author__: PPPsych
# date: 2021/1/7


# 链表类
class LinkList:
    class Node:
        def __init__(self, item=None):
            self.item = item
            self.next = None

    class LinkListIterator:
        def __init__(self, node):
            self.node = node

        def __next__(self):
            if self.node:
                cur_node = self.node
                self.node = cur_node.next
                return cur_node.item
            else:
                raise StopIteration

        def __iter__(self):
            return self

    def __init__(self, iterable=None):
        self.head = None
        self.tail 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值