如何快速找出找出两个数组中的_哈希算法详解(附带 iOS 开发中实际应用)

本文详细介绍了哈希表的设计思想、哈希函数的构造方法,包括直接定址法、平方取中法、折叠法和除留取余法,并探讨了哈希表大小的确定以及解决冲突的开放定址法和链地址法。此外,文章阐述了哈希表在实际应用中的优势和局限性,特别强调了其在iOS开发中用于实现NSMutableSet/NSSet过滤重复元素的功能,需要重写- (BOOL)isEqual:和- (NSUInteger)hash方法。通过具体的代码实现,展示了如何正确地重写这些方法以避免冲突和提高性能。
摘要由CSDN通过智能技术生成

b1fb0b0a909a94b56a4b78bd3589e284.gif

c7f0e8a4ff4aa1e8eb5f95af40d2c9c4.png

Linux编程 点击右侧关注,免费入门到精通! 467af57fceccbd95e76f56debf17688e.png

作者丨ZhengYaWeihttps://www.jianshu.com/p/2a71b027b723

6dcee24185930edf7bc32c8e6ca3d284.gif前言

哈希(Hash)或者说散列表,它是一种基础数据结构。Hash 表是一种特殊的数据结构,它同数组、链表以及二叉排序树等相比较有很明显的区别,但它又是是数组和链表的基础上演化而来,既具有数组的有点,又具有链表的有点。能够快速定位到想要查找的记录,而不是与表中存在的记录的关键字进行比较来进行查找。应用了函数映射的思想将记录的存储位置与记录的关键字关联起来,从而能够很快速地进行查找。

6dcee24185930edf7bc32c8e6ca3d284.gif一、Hash设计思想

试想如果我们对一个数组进行查询,这个数组里,每一个元素都是一个字符串。我们知道数组最快的检索办法是通过数组的下标进行检索,但是对于这种场景,我们无能为力,只能从头查到尾,从而查询出目标元素。

2fa5ae40a7ae1105adbfd97ebd86bdc0.png

如果我们要根据名字找到其中的任何一个元素,就需要遍历整个数组。最坏情况下时间复杂度是O(n) ,但是借助 Hash 可以将时间复杂度降为O(1)。

Hash表采用一个映射函数 f :key —> address 将关键字映射到该记录在表中的存储位置,从而在想要查找该记录时,可以直接根据关键字和映射关系计算出该记录在表中的存储位置,通常情况下,这种映射关系称作为Hash函数,而通过Hash函数和关键字计算出来的存储位置(注意这里的存储位置只是表中的存储位置,并不是实际的物理地址)称作为Hash地址。比如上述例子中,假如联系人信息采用Hash表存储,则当想要找到 “lisi” 的信息时,直接根据 “lisi” 和 Hash 函数计算出 Hash 地址即可。

所谓的 hash 算法就是将字符串转换为数字的算法。为了更好说明这种设计思想,笔者先设计出一种最笨的 Hash 函数,将所有字符串中的字符转化为数字后相加。

390a86d86345f697509a53920e5b7af8.png

上表中数组的下标就是字符串对应的数字值。根据对应的数字值,我们就能轻易找到任何想要的对象,时间复杂度为O(1)。

6dcee24185930edf7bc32c8e6ca3d284.gif二、Hash函数设计

所谓的 hash 算法就是将字符串转换为数字的算法。通常有以下几种构造 Hash 函数的方法:

2.1 直接定址法

取关键字或者关键字的某个线性函数为 Hash 地址,即address(key) = a * key + b; 如知道学生的学号从2000开始,最大为4000,则可以将address(key)=key-2000(其中a = 1)作为Hash地址。

2.2 平方取中法

对关键字进行平方计算,取结果的中间几位作为 Hash 地址。如有以下关键字序列 {421,423,436} ,平方之后的结果为 {177241,178929,190096} ,那么可以取中间的两位数 {72,89,00} 作为 Hash 地址。

2.3 折叠法

将关键字拆分成几部分,然后将这几部分组合在一起,以特定的方式进行转化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值