42 (OC)* 字典实现原理--哈希原理
一、NSDictionary使用原理
1.NSDictionary(字典)是使用 hash表来实现key和value之间的映射和存储的,hash函数设计的好坏影响着数据的查找访问效率。
- (void)setObject:(id)anObject forKey:(id )aKey;
2.Objective-C 中的字典 NSDictionary 底层其实是一个哈希表,实际上绝大多数语言中字典都通过哈希表实现,
二、哈希的原理
哈希概念:哈希表的本质是一个数组,数组中每一个元素称为一个箱子(bin),箱子中存放的是键值对。
三、哈希表的存储过程:
1. 根据 key 计算出它的哈希值 h。
2. 假设箱子的个数为 n,那么这个键值对应该放在第 (h % n) 个箱子中。
3. 如果该箱子中已经有了键值对,就使用开放寻址法或者拉链法解决冲突。
在使用拉链法解决哈希冲突时,每个箱子其实是一个链表,属于同一个箱子的所有键值对都会排列在链表中。
哈希表还有一个重要的属性: 负载因子(load factor),它用来衡量哈希表的 空/满 程度,一定程度上也可以体现查询的效率,计算公式为:
负载因子 = 总键值对数 / 箱子个数
负载因子越大,意味着哈希表越满,越容易导致冲突,性能也就越低。因此,一般来说,当负载因子大于某个常数(可能是 1,或者 0.75 等)时,哈希表将自动扩容。
重哈希概念:
哈希表在自动扩容时,一般会创建两倍于原来个数的箱子,因此即使 key 的哈希值不变,对箱子个数取余的结果也会发生改变,因此所有键值对的存放位置都有可能发生改变,这个过程也称为重哈希(rehash)。
哈希表的扩容并不总是能够有效解决负载因子过大的问题。假设所有 key 的哈希值都一样,那么即使扩容以后他们的位置也不会变化。虽然负载因子会降低,但实际存储在每个箱子中的链表长度并不发生改变,因此也就不能提高哈希表的查询性能。
四、总结,细心的读者可能会发现哈希表的两个问题:
1. 如果哈希表中本来箱子就比较多,扩容时需要重新哈希并移动数据,性能影响较大。
2. 如果哈希函数设计不合理,哈希表在极端情况下会变成线性表,性能极低。
42 (OC)* 字典实现原理--哈希原理的更多相关文章
- minHash最小哈希原理
		
minHash最小哈希原理 收藏 初雪之音 发表于 9个月前 阅读 208 收藏 9 点赞 1 评论 0 摘要: 在数据挖掘中,一个最基本的问题就是比较两个集合的相似度.通常通过遍历这两个集合中的所有 ...
 - 【mysql】索引原理-MySQL索引原理以及查询优化
		
转载:https://www.cnblogs.com/bypp/p/7755307.html 一.介绍 1.什么是索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性 ...
 - atitit 业务 触发器原理. 与事件原理 docx
		
atitit 业务 触发器原理. 与事件原理 docx 1.1. 呵呵,你需要需要一个业务 触发器..1 1.2. 触发器/事件/中断的原理1 1.3. Io 硬件中断的原理( 中断的低层有cpu轮询 ...
 - KVC 和 OC字典
		
KVC(键值编码)和OC 字典很相似,都是键值存储.但是OC 字典比较灵活,它是一种映射. [dict setObject:<#(id)#> forKey:<#(id<NSCo ...
 - poj2356 Find a multiple(抽屉原理|鸽巢原理)
		
/* 引用过来的 题意: 给出N个数,问其中是否存在M个数使其满足M个数的和是N的倍数,如果有多组解, 随意输出一组即可.若不存在,输出 0. 题解: 首先必须声明的一点是本题是一定是有解的.原理根据 ...
 - yum 原理C/S原理结构图
		
yum 原理C/S原理结构图
 - Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)
		
Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理) 一丶封装 , 多态 封装: 将一些东西封装到一个地方,你还可以取出来( ...
 - 转载:把你的精力专注在java,jvm原理,spring原理,mysql锁,事务,多线程,大并发,分布式架构,微服务,以及相关的项目管理等等,这样你的核心竞争力才会越来越高
		
https://developer.51cto.com/art/202001/608984.htm 把你的精力专注在java,jvm原理,spring原理,mysql锁,事务,多线程,大并发,分布式架 ...
 - Nginx基本功能及其原理,配置原理
		
Nginx基本功能及其原理,配置原理 一.正向代理.反向代理 二.Nginx配置文件的整体结构 三.Nginx配置SSL及HTTP跳转到HTTPS 四.nginx 配置管理 [nginx.conf 基 ...
 
随机推荐
- GSS系列
			
GSS1 直接维护静态区间和即可 #include<bits/stdc++.h> using namespace std; ; int n,a[N]; ]; inline void pus ...
 - idea中pom如何加载jar包依赖
			
1.需求分析 在特定需求的情况下,idea需要加载jar包,那么如何在idea中正确的配置jar依赖呢?今天博主就这个问题给大伙讲解下,希望对大伙有所帮助 2.实现方案①在工程src目录下新建l ...
 - DBUtils框架的使用(下)
			
刚才讲了使用QueryRunner插入.修改.更新数据,现在来学习一下使用QueryRunner进行数据库表查询. 通过QueryRunner类的query()方法即可完成数据库表的查询操作,但是在查 ...
 - SecureCRT软件的个性化设置
			
工欲善其事,必先利其器.如果我们能花点时间把每天工作都要用到的SecureCRT软件设置的舒服一些,日后工作起来也是会心情愉悦.事半功倍的. 1.日志文件设置 2.窗口配色和关键字高亮 3.效果展示 ...
 - Spring自定义属性编辑器及原理解释.md
			
bean的自动装配解释 手动解决方式 自动注入解决方式 bean的自动装配解释 之前有构造注入和设值注入,但是也是手动的 autowire ="byname" 这里要注意自动装配的 ...
 - Qt最新版5.12.2在Win10环境静态编译安装和部署的完整过程(VS2017)
			
一.为什么要静态编译 用QtCreator编译程序时,使用的是动态编译.编译好的程序在运行时需要另外加上相应的Qt库文件,一大堆dll文件.如果想将生成的程序连同所需要的库一起完整地打包成一个可执行程 ...
 - java杨辉三角
			
public static void main(String[] args) { Scanner scanner=new Scanner(System.in); System.out.println( ...
 - Delphi - Indy 创建邮件自动发送服务
			
服务器自动邮件线程 功能:此程序主要实现对Oracle数据库表tableName(存放需要发送邮件的相关信息)里面相关信息的邮件发送. 优点:开发人员可以直接再数据库后台对tableName表进行插入 ...
 - 【Leetcode】【简单】【189. 旋转数组】【JavaScript】
			
189. 旋转数组 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6,7] 和 k = 3输出: [5,6,7,1,2,3,4]解释 ...
 - 2019 Multi-University Training Contest 8
			
2019 Multi-University Training Contest 8 C. Acesrc and Good Numbers 题意 \(f(d,n)\) 表示 1 到 n 中,d 出现的次数 ...