《算法图解》总结第 5 章:散列表

仅用于记录学习,欢迎批评指正,大神勿喷

系列文章目录

《算法图解》总结第 1 章:二分查找、大O表示法;
《算法图解》总结第 2 章:数组和链表,选择排序;
《算法图解》总结第 3 章:while循环、递归、栈;
《算法图解》总结第 4 章:分而治之、快速排序;
《算法图解》总结第 5 章:散列表;
《算法图解》总结第 6 章:广度优先搜索;
《算法图解》总结第 7 章:狄克斯特拉算法;
《算法图解》总结第 8 章:贪婪算法
《算法图解》总结第 9 章:动态规划
《算法图解》总结第 10 章:K最近邻算法
《算法图解》总结第 11 章:十种算法简介



散列表


散列表也被称为散列映射、映射、字典和关联数组。散列表是使用散列函数和数组共同创建的一种数据结构,可以使用散列函数来确定元素的存储位置。
散列函数需要满足两个要求:
(1)输入输出必须是一致的。
(2)散列函数应将不同的输入映射到不同的数字。
散列函数能准确指出元素的存储位置,原因有三:
(1)散列函数总是将同样的输入映射到相同的索引;
(2)散列函数将不同的输入映射到不同的索引;
(3)散列函数知道数组有多大,只返回有效的索引。


一、创建散列表

算法实现:Python

# 使用dict()函数创建散列表或者令book={},{}是字典专用符号
book = dict()
# 添加元素
book["apple"]=0.67
book["milk"]=1.49
book["avocado"]=1.49
# 输出散列表
print(book)

输出结果:

{'apple': 0.67, 'milk': 1.49, 'avocado': 1.49}

二、应用案例

1.将散列表用于查找

算法实现:Python

# 使用dict()函数创建散列表或者令book={},{}是字典专用符号
book = dict()
# 添加元素
book["apple"]=0.67
book["milk"]=1.49
book["avocado"]=1.49
# 输出散列表
print(book)
#  查询苹果价格
print(book["apple"])

输出结果:

{'apple': 0.67, 'milk': 1.49, 'avocado': 1.49}
0.67

2.防止重复

假设投票站限每人只能投一票 ,为避免重复,当有人来投票,将询问他的全名,与已投票名单做对比,若名字出现在名单中,说明已投票,不允许再投,否则允许其投票,并将其名单加入已投票名单中。

算法实现:Python

voted = {}
def check_voter(name):
    # 与已投票者名单做对比
    # 能得到名字,拒之门外
    if voted.get(name):
        print "kick them out!"
    # 得不到名字,将其名字加入名单,让其投票
    else:
        voted[name] = True
        print "let them vote!"

测试用例:

check_voter("tom")
check_voter("milk")
check_voter("tom")

输出结果:

let them vote!
let them vote!
kick them out!

3.缓存/记住数据

假设在网站工作,可对网页进行缓存(如使用Google搜索时,首页有之前使用过的一些网页),缓存是一种常用的加速方式,所有大型网站都使用缓存,而缓存的数据则存储在散列表里。

# 散列表用于缓存网页数据
cache = {}
def get_data(url):
    # 若缓存有数据,直接返回数据
    if cache.get(url):
        return cache[url]
    # 若没有缓存过,查找数据,缓存数据,返回数据
    else:
        data = get_data_from_serever(url)
        cache[url]=data
        return data   

三、冲突

之前我们学到的是散列函数总是将不同的键映射到数组的不同位置,实际上,几乎不可能编写出这样的散列函数,有时会给两个键分配的位置相同,这种情况被称为冲突,处理冲突的方式:如果两个键映射到同一个位置,就在这个位置存储一个链表。
经验教训:
散列函数很重要:需要将键均匀地映射到列表的不同位置。
若散列表存储的链表很长,散列表的速度将会急速下降:若使用的散列函数很好,链表就不会长。
各种编程语言都提供了散列表实现,性能良好。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值