本文主要围绕效率开始说起
常见算法效率复杂度
O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)
python列表内置操作方法的复杂度如下
常见的顺序表存储方式如下,python则采用的是分离式结构,表头只存储最大容量值,元素个数和存储区的物理地址,
存储区的结构示意图,其中存储区域涉及的主要知识点为扩容问题,python采用的是容量加倍的方式,但当元素超过50000个时,其便会改变策略,以避免不必要的浪费
扩充的两种策略
Python标准类型list就是一种元素个数可变的线性表,可以加入和删除元素,并在各种操作中维持已有元素的顺序(即保序),而且还具有以下行为特征:
基于下标(位置)的高效元素访问和更新,时间复杂度应该是O(1);
为满足该特征,应该采用顺序表技术,表中元素保存在一块连续的存储区中。
允许任意加入元素,而且在不断加入元素的过程中,表对象的标识(函数id得到的值)不变。
为满足该特征,就必须能更换元素存储区,并且为保证更换存储区时list对象的标识id不变,只能采用分离式实现技术。
在Python的官方实现中,list就是一种采用分离式技术实现的动态顺序表。这就是为什么用list.append(x) (或 list.insert(len(list), x),即尾部插入)比在指定位置插入元素效率高的原因。
优质链接参考:https://cloud.tencent.com/developer/article/1489092
https://www.jianshu.com/p/cd75475168ae
dict分析
字典是通过散列表或说哈希表实现的。字典也被称为关联数组,还称为哈希数组等。也就是说,字典也是一个数组,但数组的索引是键经过哈希函数处理后得到的散列值。哈希函数的目的是使键均匀地分布在数组中,并且可以在内存中以O(1)的时间复杂度进行寻址,从而实现快速查找和修改。哈希表中哈希函数的设计困难在于将数据均匀分布在哈希表中,从而尽量减少哈希碰撞和冲突。由于不同的键可能具有相同的哈希值,即可能出现冲突,高级的哈希函数能够使冲突数目最小化
什么是hash冲突?
假设hash表的大小为9(即有9个槽),现在要把一串数据存到表里:5,28,19,15,20,33,12,17,10
简单计算一下:hash(5)=5, 所以数据5应该放在hash表的第5个槽里;hash(28)=1,所以数据28应该放在hash表的第1个槽里;hash(19)=1,也就是说,数据19也应该放在hash表的第1个槽里——于是就造成了碰撞(也称为冲突,collision
解决hash冲突,python采用开放地址法,java和redis都采用链接方法
关于开放地址法与链接优缺点https://zhuanlan.zhihu.com/p/33496977
原文链接:https://blog.csdn.net/answer3lin/article/details/84523332
开放地址法的具体实现