009.查找手机电话簿【散列表】
1. 散列表
顺序存储的结构类型需要一个一个地按顺序访问元素,当总量很大且我们所要访问的元素比较靠后时,顺序存储的结构类型性能就比较低。而散列表是一种空间换时间的存储结构,也是提升效率的一种比较常用的方式。由于它所需空间太大,所以通常需要使用者在“效率”和“占空间大小”二者之间权衡。
1.1 什么是散列表
利用字典查找汉字的过程就是散列表的思想。散列表,又叫作哈希表,是通过给定的关键字直接访问到具体对应值的数据结构。简单的说,就是把关键字映射到一个表中的位置来直接访问记录,以加快访问速度。通常把关键字称为Key,把对应的记录称为Value,把存放记录的数组叫作散列表。
1.2 散列函数
散列函数又称为哈希函数,给定一个输入 x (任何数据),它都会算出相应的输出 H(x)(一般为数字)。散列表具有如下特征:
- 输入 x 可以是任意字符串
- 输出结果 H(x) 的长度是固定的
- 计算 H(x) 的过程是高效的
- 尽可能输入一个 x 就能得出唯一的 H(x)
散列函数之所以最终会输出数字,是因为散列函数计算出的数字需要用来做索引。
1.3 解决散列表的冲突
1.3.1 开放定址法
开放定址法就是当数据的散列地址遇到冲突,系统就会去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,系统将记录存入该散列地址。
H(i)=(H(key)+d(i)) MOD m
- key: 要存储的数据
- H(key):散列函数
- m:散列表长度
- d(i):增长序列
- MOD:%
其中,d(i) 有三种取法:
- 线性探测法:d(i)=1,2,3,4,…,m-1
- 平方探测法:d(i)=12,22,32,42,… 或 d(i)=-12,-22,-32,-42,…
- 伪随机探测法:d(i)=伪随机数序列
线性探测法:以线性的方式向散列表后面寻找空的存储位置,一旦找到位置就将数据放进去。
平方探测法:线性探测法有一个缺点,就是相类似的键值经常会聚集在一起。当多个数据键值类似时,它们就会聚集,会产生冲突。为了防止这样的事情发生,在线性的基础上做了改进,使用平方探测法:d(i)=12,22,32,…
伪随机探测法:伪随机探测法指 d(i) 采用随机函数计算得到的。如果设置的随机种子相同,则不断调用随机数可以生成不会重复的数列。在查找时,用同样的随机种子每次得到的数据是相同的,相同的数据产生相同的d(i) ,相同的 d(i) 就会得到相同的散列地址。
1.3.2 链地址法
链地址法就是将经过散列函数得到的相同的数值(索引值)放在同一个位置,就在这个位置存储为一个单链表。用专业术语描述就是将相同的键映射到同一个位置。散列表中只存储头指针,相同的数据放到同义词子表。
对于可能会造成很多冲突的散列函数来说,链地址法提供了绝不会出现找不到地址的保障,但这种方法也带来了缺点:查找数据时增加了遍历单链表的时间。
1.3.3 再散列函数法
再散列函数法就是一开始就先设置一些散列函数(比如除留取余、平方取中、折叠等等),如果使用第一种散列函数出现冲突就改用第二种,如果第二种也出现冲突就改用第三种,一直到没有冲突为止。
虽然再散列函数法不易产生聚集,但是从步骤上看,明显增加了计算时间。
1.3.4 建立公共溢出区法
建立公共溢出区法就是将散列表分为基本表和溢出表两部分,凡是与基本表发生冲突的,都存放在溢出表中。
这种方法在查找数据时,在散列函数计算出索引位置后,先与基本表的相应位置做比较,如果相等,就查找成功;如果不相等,就到溢出表中进行顺序查找。就相对查询而言,在少量数据冲突的情况下,公共溢出区法对查找数据的速度来说是比较快的。
1.3.5 解决冲突方法的比较
方法 | 优点 | 缺点 |
线性探测法 | 简单易懂 | 容易造成大量元素在相邻的散列地址上聚集,降低查询效率 |
平方探测法 | 避免出现聚集问题 | 不能探测到散列表上所有的单元,但至少探测到一半的单元 |
伪随机探测法 | 随机产生散列地址 | 用同样的随机种子,将得到相同的数列 |
链地址法 |
1. 对于记录总数频繁可变的情况,处理的比较好 2. 记录存储在结点时,动态分配内存,不浪费内存 3. 删除记录,处理方便 |
存储记录随机分布,散列表跳转访问速度慢 |
在散列函数法 | 不易产生聚集 | 增加了计算时间 |
建立公共溢出区 | 冲突数据少时,查询速度快 | 多增加了一个散列表 |
元素少,用开放定址法,冲突少,速度快;元素多,用链地址法。
1.4 散列表的性能
负载因子:也称为填装因子,负载因子度量的是散列表中有多少位置是空的。
a=n/m
- a:负载因子
- n:散列表中键值的个数
- m:散列表的大小
负载因子值=1,说明每个元素都有自己的位置。
负载因子值<1,说明还有空位置。
负载因子值>1,说明位置不足,需要调整长度,增加散列表中的位置。
总结:负载因子越低,发生冲突的可能性越小,散列表的性能越高。
时间性能:在理想的情况下,散列表执行各种操作的时间都是 O(1),也就是常量时间。即使有 1 亿条数据,它的运行时间也是相同的,所以说在各种条件相同的情况下,散列表的查询速度最快。
2. 查找手机电话簿
散列表广泛应用于查找,例如查找员工信息,学生信息,电话簿等等。下边列举如何快速查找到联系人的信息。
# 创建散列表
# TelephoneBook=dict()
# TelephoneBook={}
TelephoneBook=dict(阿美='187-6667-****',阿彪='186-****-4544',爸爸='136-9475-****',白雪='136-1231-****',陈明='178-****-9490')
print("电话薄信息如下:")
# 输出完整散列表
print(TelephoneBook)
print('')print("查找联系人“白雪”的信息:")
# 查找白雪信息并输出
print("姓名:白雪 电话号码:",TelephoneBook['白雪'])
print('')# 添加“彩虹”信息
TelephoneBook['彩虹']="188-****-5556"
print("添加彩虹之后的完整电话薄:")
# 输出添加之后的完整散列表
print(TelephoneBook)
print('')# 修改“阿彪”信息
TelephoneBook['阿彪']="178-****-5555"
print("修改阿彪之后的完整电话薄:")
# 输出修改之后的完整散列表
print(TelephoneBook)
print('')# 删除“白雪”信息
del TelephoneBook['白雪']
print("删除白雪之后的完整电话薄:")
# 输出删除之后的完整散列表
print(TelephoneBook)
009.查找手机电话簿【散列表】相关推荐
- 【数据结构-查找】3.散列表详解
散列表的一些基本概念 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度 ...
- 利用开放定址法实现散列表的创建、插入、删除、查找操作_散列表和IO
散列表(也叫哈希表) 直接寻址法 取关键字或关键字的某个线性函数值为散列地址.即H(key)=key或H(key) = a·key + b,其中a和b为常数(这种散列函数叫做自身函数).若其中H(ke ...
- 数据结构课程设计------c实现散列表(二次探测再哈希)电话簿(文件存储)
题目二 :散列表的设计与实现 2.1问题描述 设计散列表实现电话号码查找系统,使得平均查找长度不超过2 基本要求 (1)设每个记录有下列数据项:电话号码.用户名.地址: (2)从键盘输入各记录,以电话 ...
- 数据结构与算法之hashmap散列表查找
哈希表:关键字.地址与查找 哈希查找是一种常用的查找方式,通常通过自定义函数F(关键字)来实现对于元素的查找,并返回关键字的存储地址(查找成功)或"查找失败"讯息. 散列表不同于线 ...
- 《数据结构与算法》(二十)- 散列表查找
目录 前言 1. 散列表查找(哈希表)概述 1.1 散列表查找定义 1.2 散列表查找步骤 2. 散列函数的构造方法 2.1 直接定址法 2.2 数字分析法 2.3 平方取中法 2.4 折叠法 2.5 ...
- 查找——散列表的散列函数及冲突的处理办法
查找 8.7 散列表 8.7.1 散列表的基本概念 8.7.2 散列函数 总结 8.7.3 处理冲突的闭散列方法--开地址方法 总结 闭散列方法的实现 8.7.4 处理冲突的开散列方法--链地址法 8 ...
- 18 | 散列表(上):Word文档中的单词拼写检查功能是如何实现的?
问题引入 在 Word 里输入一个错误的英文单词,它就会用标红的方式提示"拼写错误",Word 文本编辑器的拼写检查功能是如何实现的呢?散列表(Hash Table) 散列表 散列 ...
- 【数据结构与算法】散列表
一.散列表的由来? 1.散列表来源于数组,它借助散列函数对数组这种数据结构进行扩展,利用的是数组支持按照下标随机访问元素的特性. 2.需要存储在散列表中的数据我们称为键,将键转化为数组下标的方法称为散 ...
- 数据结构之查找算法:散列查找
查找算法:散列查找 思维导图: 散列函数和散列表: 构造散列函数的要求: 构造散列函数的方法: 直接定址法: 除留取余法: 数字分析法: 平方取中法: 折叠法: 解决冲突的方法: 开放定址法: 线性探 ...
最新文章
- idea批量修改变量快捷键mac_使用Mac自带功能批量修改图片名称、类型和压缩图片大小...
- 「镁客·请讲」快仓杨威:赋予仓库灵魂,让智能仓库系统自我进化和迭代
- 表现层持续解耦带来的模式转变 MVC MVP MVVM
- 安卓开发网络资源汇总
- excel单元格下拉菜单
- TCP通信的服务器端代码实现
- Software optimization resources
- linux 正则表达式和通配符
- LeetCode 688. “马”在棋盘上的概率
- Zookeeper - zookeeper安装与配置
- 启明星系统字体的演变
- native2ascii
- 交换机基本原理与配置(包含ensp交换机配置命令)
- FPGA工程师面试试题集锦11~20
- Python爬虫之豆瓣TOP250爬取
- PHP+MYSQL 用户注册登录代码
- 《如何设计一个秒杀系统》——专栏笔记
- MySQL数据库——初识MySQL
- BeautifulSoup详解
- 信息论的应用例子:数据压缩与信息熵、为什么K线这种技术指标没用了?
热门文章
- Lazada商家售出产品多久能收款?收款方式及流程一篇详解!
- Win10下运行红色警戒2
- 利用python爬取教务系统中成绩
- latex显示错误:Text line contains an invalid character. l.1
- DSP C6657 image_processing_evmc6657l网页加载图片示例
- 怎么看计算机版本号,如何查看电脑windows版本号(查看电脑版本信息的11种方法)...
- 整数平方一定大于零吗?
- Go语言核心之美 3.3-Map
- 安卓移动办公软件_尚朋高科TeeTek云端移动办公系统,云端软件5G时代的趋势
- IT职业病预防之颈椎病(一)