数据结构与算法之美-散列表-极客时间笔记

2024-05-31 04:48

本文主要是介绍数据结构与算法之美-散列表-极客时间笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

散列表或者哈希表,就是数组的一种延伸应用,主要还是利用数组可以方便的理由下标索引进行元素操作。概念的核心点在于原始数据可能是键值对,将Key值通过哈希函数进行转化变成唯一(希望是唯一,但并无法保证,所以才有后面的散列冲突问题)的下标索引,以此来保证Value值。

 散列函数的设计有下列三点要求:

1、散列函数计算得到的散列值是一个非负整数;——因为散列的结果对应数组下标,必要要求非负整数。

2、如果 key1 = key2,那 hash(key1) == hash(key2);——相同Key对应的散列值要一致,涉及第一次存储和后续读取

3、如果 key1 ≠ key2,那 hash(key1) ≠ hash(key2)。——最好的结果是不同的Key对应不同的散列值,这样才能区分

但第三点是没办法实现的,因为无论如何数组大小是有限的,而可能的Key是无限的,这样用有限去对应无限,必然是会出现重复,这就是所谓的散列冲突问题。

处理散列冲突常用的有两种方法:开发寻址法和链表法。

1、开放寻址法是当遇到散列值被使用的情况下就继续做数组中顺序寻找空闲位置,这样会有个缺点,就是如果散列冲突很多的时候,这种顺序去查找的时间就会变得特别长。而且还有个问题就是,如果不是哈希插入,而是哈希查找。一般来说是发现空闲位置前还没有发现目标元素则认为元素不在散列表。但是如果数组之前有元素被删除,相应位置出现空缺,就会错误的认为元素不在散列表。虽然可以用删除标记来表示,但这种方法还是不够方便,实际应用不多。

2、链表法,如果出现散列值相同的情况,就在相应位置建立1条链表,只要散列的分布足够均匀,不让大多数散列值相同,就不会让散列表退化。不然很多元素在一个散列值组成链表就容易变成单链表。

为了尽可能保证散列表的操作效率,一般情况下,我们会尽可能保证散列表中有一定比例的空闲槽位。我们用装载因子(load factor)来表示空位的多少。装载因子是目前已装入元素个数除以数组长度。装载因子越大,说明空闲位置越少,冲突越多,散列表的性能会下降。

一个能应对各种异常情况的工业级散列表也应该从上述三方面出发:

1、散列函数的设计,不能过于复杂,因为散列值会需要经常计算,复杂计算势必会影响到性能;另外散列函数的结果要尽可能随机且平均分布,减少散列冲突的可能。

2、装载因子可以作为散列表是否需要扩容的因素指标,当到底某个阈值后启动动态扩容,将旧散列表的数据迁移至新散列表。虽然这种操作经过均摊还是O(1),但是对于那一次来说,用户体验还是糟糕。可以将摊还真实的进行分割,旧数据迁移不是一次进行,而是伴随新数据存入同步进行,这样就对于每个用户来说时间都不会太明显。

3、根据使用场景选择合适的散列冲突解决方法。当数据量比较小、装载因子小的时候,适合采用开放寻址法。利用数组的优点,但更加消耗内容,因为散列冲突的影响更加严重。基于链表的散列冲突处理方法比较适合存储大对象、大数据量的散列表,而且,比起开放寻址法,它更加灵活,支持更多的优化策略,比如用红黑树代替链表。

散列表这种数据结构虽然支持非常高效的数据插入、删除、查找操作,但是散列表中的数据都是通过散列函数打乱之后无规律存储的。也就说,它无法支持按照某种顺序快速地遍历数据。如果希望按照顺序遍历散列表中的数据,那我们需要将散列表中的数据拷贝到数组中,然后排序,再遍历。那效率势必会很低。为了解决这个问题,我们将散列表和链表(或者跳表)结合在一起使用。可以看下图这个缓存系统的数据结构:

上图存在两种链表,一种是表示缓存更新时间的双向链表,另一种是散列表中用于解决散列冲突的链表。可以在O(1)时间里实现查找、删除、增加。散列表用于查找元素,删除和增加利用双向链表的指针也可以快速实现。

 

 

这篇关于数据结构与算法之美-散列表-极客时间笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1017399

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)