数据结构与算法之散列表详解

news/2024/11/25 21:57:30/

一、散列表概述

散列表(Hash Table)也叫哈希表,它是一种时间复杂度能够达到接近常数的数据结构,可以用来快速地存储和查找数据。散列表通过哈希函数来将键值对映射为一个索引值,然后通过这个索引值来在数组中访问对应的存储位置。

要求一个哈希函数必须满足以下三点:

1、确定性:哈希函数对于一定的键值总是返回相同的哈希值。这是哈希表中非常基本的要求。

2、均匀性:哈希函数应该能够把键尽可能均匀地映射到不同的桶中。如果哈希函数能够把每一个键均匀地分布到散列表中的每一个桶内,那么搜寻的时间复杂度就可以近似于O(1)。

3、高效性:对于特定的键值,哈希函数应当能够高效地计算出它的哈希值。

二、哈希冲突

尽管我们可以构造一些不错的哈希函数,也能将键值均匀地分布到桶内,但是任何一个哈希函数都无法完全避免哈希冲突。哈希冲突是指两个不同的键被哈希函数映射到了同一个索引值的现象。

哈希冲突会影响散列表的效率。当然,这个影响是有限的,因为在搜索过程中依然有办法快速地找到相应的键值。

解决哈希冲突的方法分为两种,一种是开放地址法,另一种是链表法。

1、开放地址法

开放寻址法的思想是在哈希发生冲突时,寻找下一个可用位置,直到存储空间的总大小不变。简单的开放地址法的实现包括线性探测、二次探测和二次哈希。开放地址法的优点是实现简单,内存消耗低,但是它的缺点是容易出现二次聚拢问题,即表中的元素会聚集在一块。解决这个问题的方法包括使用链表法。

2、链表法

链表法是在哈希表中每个位置使用一个链表来存储多个键值对。当哈希函数在某个位置发生冲突时,新的键值对会被添加到这个位置的链表中。链表法的优点是可以存储大量的键值对,并且这个方法最差情况下,时间复杂度也不太容易超过O(n)。

三、散列函数

散列函数是将键映射为索引值的算法。散列函数应该对于不同的键映射成不同的索引值,把它们均匀地分布在散列表中。较好的散列函数所使用的算法应该是能够在较短时间内计算出散列值。

主要的散列算法有三种:折叠法、平方取中法以及MD5哈希算法。

1、折叠法

折叠法是将键切分成几部分,然后将每一部分相加,从而得到散列值。下面的示例代码示范了一个比较简单的折叠法实现:

int fold(char *str, int len) {int sum = 0;for (int i = 0; i < len; i++) {sum += str[i];}return sum;
}

2、平方取中法

平方取中法是先将给定的键乘以它本身,然后取得结果的一部分作为散列值。这样可以保证散列值的均匀性。下面的代码示例实现了平方取中法:

int square(char *str, int len) {int sum = 0;for (int i = 0; i < len; i++) {sum += pow(str[i], 2);}return (sum / 100) % 10000;
}

3、MD5哈希算法

MD5哈希算法是一种非常流行的散列算法,它能够生成一个128位的散列值。MD5哈希算法得到的散列值是唯一的、确定的,这是保证散列值分布均匀的基础。MD5哈希算法的实现代码较长,这里就不展示了。

四、散列表的应用

散列表在实际工作中有着广泛的应用,下面介绍散列表在几个重要领域中的应用:

1、数据结构

散列表可以用作数据结构,存储和查找数据。散列表的查找、插入和删除操作具有较高的效率,能够满足大规模数据的存储和查找需求。

2、编译器

编译器完全基于散列表的编译模块是提高编译效率的关键。散列表通过处理变量之间的引用和跳转位置,实现了编译和链接操作。散列表在很多编程语言的编译器中都得到了广泛应用。

3、缓存

缓存是一种高性能的数据存放方式,它可以大幅度提高程序运行的速度。缓存的实现和散列表的结构很相似。通过缓存散列表,我们可以把经常访问的数据放到缓存中,使得这些数据的查询如同在内存中一样高效。

4、数据库

大多数数据库使用散列表来存储索引,这样可以加速数据库的查询操作。散列表与数据库内部的B+树结构结合使用,可以提高数据库查询的效率。

5、路由器

路由器是互联网中最重要的设备之一,它能够将数据包从一个地方传送到另一个地方。路由器内部的许多算法都基于散列表,通过散列表可以很快地查找到对应的端口号,实现数据包的转发和路由。

五、散列冲突的分析

在设计散列函数时需要尽可能的使冲突率尽可能的小,但是不可能完全避免。假设m个关键字被均匀地散布在一个大小为p的区域内,散列表的长度为m,我们可以估算出散列表的容量为: c = m/p。

如果冲突是随机发生的,则期望一个含k个关键字的桶中散列冲突的数量约为 k^2 / (2c)。当冲突率增加时,平均的查找次数也就随着增加。因此要尽量避免散列冲突,或及时的解决散列冲突才能保证散列表的操作效率。

六、总结

散列表(哈希表)是一种基于散列函数实现的数据结构,它通过哈希函数将键映射为存储位置,以此快速地存储和查找数据。

散列表具有以下优点:查找、插入和删除操作的时间复杂度可以超过线性表和树,几乎是常数时间;存储量大时,散列表比线性表和树结构更省空间。但是如果哈希函数设计不好,也容易发生哈希冲突,影响散列表的性能。

为了解决哈希冲突问题,可以采用开放地址法和链表法两种方法。开放地址法将键映射到的桶已经被占用时,继续寻找下一个可用桶;链表法则是将键冲突的元素通过链表的形式进行存储,不断添加新元素到对应桶的链表上。

散列函数是实现散列表的关键,它对于散列冲突的发生率和查找效率都有至关重要的影响。常用的散列算法有折叠法、平方取中法和MD5哈希算法。

散列表广泛应用于数据结构、编译器、缓存、数据库、路由器等领域中。在实际使用中,需要根据具体情况选择合适的散列函数和解决哈希冲突的方法,以及合适的散列表长度,才能使散列表发挥最优效果。


http://www.ppmy.cn/news/75065.html

相关文章

【数据库】SQLServer报修表,维修表,反馈表三表连查

大家好&#xff0c;我是雷工&#xff01; 最近参与的一个SCADA项目&#xff0c;客户要求增加设备维保的功能&#xff0c;对设备的报修&#xff0c;维修&#xff0c;反馈过程进行记录查询&#xff0c;进一步提升企业的信息化能力。 该过程的实现是通过创建三个表分别记录报修-维…

【0196】共享内存管理结构(shmem)之创建共享内存分配机制(Shared Memory Allocation)(2)

文章目录 1. 共享内存段(Shared Memory Segment)1.1 设置指向共享内存的基本指针2. 创建共享内存分配机制相关文章: 【0195】共享内存管理结构(shmem)之概念篇(1) 【0

Linux下安装配置maven

1.安装以及配置maven 1.1.下载maven安装包 首先需要切换到自己需要安装的目录 把配置都放到了&#xff1a;/root路径下 1.2.解压下载好的maven包 tar -zxvf apache-maven-3.6.0-bin.tar.gzcp -r apache-maven-3.6.0 /usr/local/1.3.配置maven环境变量 1.3.1.在环境变量中…

maven安装与配置

这里写目录标题 一、maven的下载二、配置环境变量三、setting.xml文件配置四、idea集成maven 一、maven的下载 maven官网 我准备好的maven解压即用&#xff0c;提取码&#xff1a;0221 二、配置环境变量 (1) 我的电脑 -> 属性 -> 高级系统设置 -> 环境变量 -> …

Windows本地快速搭建SFTP服务共享文件【外网访问】

文章目录 1. 搭建SFTP服务器1.1 下载 freesshd服务器软件1.3 启动SFTP服务1.4 添加用户1.5 保存所有配置 2 安装SFTP客户端FileZilla测试2.1 配置一个本地SFTP站点2.2 内网连接测试成功 3 使用cpolar内网穿透3.1 创建SFTP隧道3.2 查看在线隧道列表 4. 使用SFTP客户端&#xff0…

算法Day09 | KMP,28. 实现 strStr() ,459.重复的子字符串

Day09 KMP28. 实现 strStr()459.重复的子字符串 KMP KMP是三个人人名缩写&#xff0c;用于在文本字符串text中搜索pattern字符串&#xff0c;返回在text中第一出现的位置。 算法做法就是在暴力匹配的基础上加速匹配。通过对pattern字符串求next数组(该数组也成为前缀表)&#…

gitlab建立新分支提交,cherry-pick部分更新

gitlab介绍 GitLab是一个基于Git的在线代码托管和协作平台&#xff0c;提供源代码管理、单元测试、CI/CD构建、代码审查等功能。它是一个开放源代码的Git仓库管理系统&#xff0c;使用 Ruby on Rails 构建GitLab 不仅具有自己的 Git 仓库管理系统&#xff0c;还具有很多其他的…

SpringSecurity权限管理基本概念和整体架构介绍

文章目录 一、权限管理1、认证2、授权3、对权限控制&#xff0c;现有的解决方案 二、SpringSecurity简介1、官方定义2、历史 三、整体架构1、认证AuthenticationManagerAuthenticationSecurityContextHolder 2、授权AccessDecisionManagerAccessDecisionVoterConfigAttribute 一…