时间复杂度

数组介绍

倾然丶 夕夏残阳落幕 提交于 2020-03-03 02:19:54
什么是数组? 数组是一种线性表数据结构,它用一组连续的的内存空间,来存储一组具有相同类型的数据。 数组如何实现随机访问? 基于数组的两大特性:线性表结构和连续的内存空间和相同类型的数据,使得数组可以通过下标直接访问数组元素,从而具有“随机访问”的特性。 具体实现方法: 当计算机需要随机访问数组中的某个元素时,通过寻址公式计算出该元素存储的内存地址,寻址公式如下所示: a[i]_address = base_address + i * data_type_size 其中 i 为数组元素的下标(从0开始),data_type_size 表示数组中每个元素的大小,假如数组中存储的是 int 类型数据,那么 data_type_size 就为4个字节。 数组查找的时间复杂度 根据下标随机访问的时间复杂度为 O(1)。 注意:前提条件是根据下标进行的随机访问,如果是在下标不确定的情况下查找某个元素,那么即便是已经排好序的数组,你用二分查找,时间复杂度也是 O(logn)。 低效的“插入”和“删除” 数组为了保持内存数据的连续性,会导致插入、删除操作比较低效,具体是为什么呢? 插入操作 每当在数组中插入一个新元素的时候,为了给这个新插入的元素挪出一个位置,我们可能需要移动大量的元素。 假设数组的长度为 n,如果在数组的末尾插入元素,那就不需要移动数组了,所以最好时间复杂度为 O(1)

排序算法总结二

偶尔善良 提交于 2020-03-02 18:06:31
本文接排序算法总结一 3. 冒泡排序 冒泡排序的基本思想:以正序排列为例,我们首先要将最大的数沉到最底下,从第一个数开始,比较相邻的两个数,如果为逆序则交换这两个数,重复这个操作直到倒数第二个数,此时最大的数已沉到最底下;然后再从第一个数开始,用同样的方法将次大的数沉到次底下,重复这个过程直到排序成功。代码如下: void PaoSort1(vector<int>& a) { int length = a.size(); for (int i = 0; i < length - 1; i++) { for (int j = 0; j < length -1-i; j++) { if (a[j]>a[j+1]) Swap(a[j], a[j+1]); } } } 注意上面的内循环j的判断条件,每当外部循环i加1表示,底部多了一个数,所以j跳出条件为length-1-i,这个过程其实是泡沫沉底。而真正的冒泡是从底部向上升,这个过程与沉底类似,只不过内部循环中的j从最后一个数开始,每次循环后j值递减,而循环跳出条件为j<i. 上述代码的缺点是当序列已经有序了,而循环没有结束,会继续进行比较操作,这样便增加了运行时间。为了提高速度我们可以设置一个标记来查看是否进行了交换,并把这个标签加入到外部循环的判断条件,这样如果没有交换说明已经排序完成,程序返回。代码如下: void Paosort2

数据结构相关

白昼怎懂夜的黑 提交于 2020-03-02 16:58:18
记录一下数据结构的一些东西,方便复习应用 二叉树 结点的度:结点拥有的子树的数目 叶子结点:度为0的结点 分支结点:度不为0的结点 树的度:树中结点的最大的度 层次:根结点的层次为1,其余结点的层次等于该结点的双亲结点的层次加1 树的高度:树中结点的最大层次 森林:0个或多个不相交的树组成。对森林加上一个根,森林即成为树;删去根,树即成为森林。 满二叉树 定义:高度为h,并且由2h-1个结点组成的二叉树,称为满二叉树 完全二叉树 定义:一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下层的叶结点集中在靠左的若干位置上,这样的二叉树称为完全二叉树。 树的遍历 详解链接 前序遍历-根左右 中序遍历-左根右 后序遍历-左右根 根据前序遍历中序遍历推导树的结构、根据树的中序遍历后序遍历推导树的结构 详细讲解 链表 详细讲解 注意 区分 node 和 node.val 链表和数组的区别: 两者的区别: 数组静态分配内存,链表动态分配内存。 数组在内存中是连续的,链表是不连续的。 数组利用下标定位,查找的时间复杂度是O(1),链表通过遍历定位元素,查找的时间复杂度是O(N)。 数组插入和删除需要移动其他元素,时间复杂度是O(N),链表的插入或删除不需要移动其他元素,时间复杂度是O(1)。 JS查找算法 https://www.cnblogs.com/zhuochong/p

HashMap O(1) 复杂度的分析

六月ゝ 毕业季﹏ 提交于 2020-03-02 11:38:27
**C++**在使用STL时,经常混淆的几个数据结构, map,hash Map,unordered_map 事实上,三个容器,有着比较大的区别. Map 内部数据的组织,基于红黑树实现,红黑树具有自动排序的功能,因此map内部所有的数据,在任何时候,都是有序的。 所以复杂度为 O(LogN) Hash map 基于哈希表,数据插入和查找的时间复杂度很低,几乎是常数时间,而代价是消耗比较多的内存。底层实现上,使用一个下标范围比较大的数组来存储元素,形成很多的桶,利用hash函数对key进行映射到不同区域(桶)进行保存。 插入 得到key, 通过hash函数得到hash值 根据hash值 找到对应的桶号(区域), hash值对(桶数)求模 存放key和value 在对应桶内 取值 分四步: 判断key,根据key算出索引。 根据索引获得索引位置所对应的键值对链表。 遍历键值对链表(当每个桶内只有一个元素时,查找时只进行一次比较),根据key找到对应的Entry键值对。 拿到value。 分析: 以上四步要保证HashMap的时间复杂度O(1),需要保证每一步都是O(1),现在看起来就第三步对链表的循环的时间复杂度影响最大,链表查找的时间复杂度为O(n),与链表长度有关。我们要保证那个链表长度为1,才可以说时间复杂度能满足O(1)。但这么说来只有那个hash算法尽量减少冲突

一.时间复杂度和空间复杂度

落爺英雄遲暮 提交于 2020-03-02 10:35:28
时间复杂度:评估执行程序所需的时间。可以估算出程序对处理器的使用程度。 空间复杂度:评估执行程序所需的存储空间。可以估算出程序对计算机内存的使用程度。 大O表示法 O(f(n)) 中的 f(n) 的值可以为1、n、logn、n^2 等,所以我们将O(1)、O(n)、O(logn)、O( n^2 )分别称为常数阶、线性阶、对数阶和平方阶。下面我们来看看推导大O阶的方法: 推导大O阶 推导大O阶有一下三种规则: 用常数1取代运行时间中的所有加法常数 只保留最高阶项 去除最高阶的常数 比如 3*n2 + 2n + 1,那么时间复杂度为O(n2) 常见时间复杂度的比较 O(1)<O(logn)<O(n)<O(nlogn)<O(n²)<O(n³)<O(2ⁿ)<O(n!) 空间复杂度较为简单,仅仅是该函数内申请内存的大小。 来源: oschina 链接: https://my.oschina.net/u/2252538/blog/3184932

分析pop()和pop(i)的性能差异-python

六月ゝ 毕业季﹏ 提交于 2020-03-02 04:18:46
《Python数据结构与算法分析》(第二版) pop()时间复杂度O(1) pop(i)时间复杂度O(n) 1. 针对一个已知长度的列表,分别从列表头和列表尾弹出一个元素 import timeit x = list ( range ( 2000000 ) ) y = list ( range ( 2000000 ) ) # 在测试中使用列表对象x,可以只对pop语句计时,从而准确得到这个操作的耗时 # 因为重复计时了1000次,所以列表每次循环都少一个元素,但列表的初始长度是200万,因此对整体长度来说,只减少了0.05% popzero = timeit . Timer ( "x.pop(0)" , "from __main__ import x" ) print ( "pop(0) " , popzero . timeit ( number = 1000 ) ) popend = timeit . Timer ( "y.pop()" , "from __main__ import y" ) print ( "pop() " , popend . timeit ( number = 1000 ) ) 运行结果: 测试结果虽然说明pop(0)确实比pop()慢,但并没有证明pop(0)的时间复杂度是O(n),也没有证明pop()的时间复杂的是O(1)

如何优雅地删除Redis大键

安稳与你 提交于 2020-03-02 02:14:58
关于Redis大键(Key),我们从[空间复杂性]和访问它的[时间复杂度]两个方面来定义大键。 前者主要表示Redis键的占用内存大小;后者表示Redis集合数据类型(set/hash/list/sorted set)键,所含有的元素个数。以下两个示例: 1个大小200MB的String键(String Object最大512MB);内存空间角度占用较大 1个包含100000000(1kw)个字段的Hash键,对应访问模式(如hgetall)时间复杂度高 因为内存空间复杂性处理耗时都非常小,测试 del 200MB String键耗时约1毫秒, 而删除一个含有1kw个字段的Hash键,却会阻塞Redis进程数十秒。所以本文只从时间复杂度分析大的集合类键。删除这种大键的风险,以及怎么优雅地删除。 在Redis集群中,应用程序尽量避免使用大键;直接影响容易导致集群的容量和请求出现”倾斜问题“,具体分析见文章: redis-cluster-imbalance 。但在实际生产过程中,总会有业务使用不合理,出现这类大键;当DBA发现后推进业务优化改造,然后删除这个大键;如果直接删除它,DEL命令可能阻塞Redis进程数十秒,对应用程序和Redis集群可用性造成严重的影响。 直接删除大Key的风险 DEL命令 在删除单个集合类型的Key时,命令的时间复杂度是O(M)

《数据结构与算法》—— O(3N)=O(N) ?

家住魔仙堡 提交于 2020-03-01 22:52:24
上帝的磨盘转动很慢,但是却磨得很细。 ——毛姆 本文已经收录至我的GitHub,欢迎大家踊跃star 和 issues。 https://github.com/midou-tech/articles 数据结构的基本概念 数据结构 相互之间存在一种或多种特定关系的数据元素的集合,我总结一下就是描述数据关系的一种载体。 数据结构包括逻辑结构和存储结构两个层次的描述。 逻辑结构 描述数据逻辑关系的一种方式,与数据的存储无关。逻辑结构中数据元素之间的关系主要分为四种:集合结构、线性结构、树结构、图结构。所有的数据结构在逻辑上都可以用这四种中的一种。 存储结构 数据和数据元素逻辑关系的存储对象,也被称为物理结构。通常逻辑结构包含两种,链式存储和顺序存储。 顺序存储 数据元素存储在一块连续的内存空间上,例如数组,就是一块连续的空间。 链式存储 数据存储不一定在一块连续的内存空间上,例如单链表。 数据类型 是一组值的集合和定义在这个集合上的操作的总称。 抽象数据类型 由用户定义的表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称,具体包括三部分,数据对象、数据对象上关系的集合以及对数据对象基本操作的集合。 抽象数据类型有自己的定义格式: ADT 抽象数据对象名 { 数据对象:(数据对象的定义) 数据关系:(数据关系的定义) 基本操作:(基本操作的定义) } 算法与数据结构 算法

《数据结构与算法》—— O(3N)≈O(N) O(3N)=O(N)?

自作多情 提交于 2020-03-01 22:25:41
上帝的磨盘转动很慢,但是却磨得很细。 ——毛姆 本文已经收录至我的GitHub,欢迎大家踊跃star 和 issues。 https://github.com/midou-tech/articles 数据结构的基本概念 数据结构 相互之间存在一种或多种特定关系的数据元素的集合,我总结一下就是描述数据关系的一种载体。 数据结构包括逻辑结构和存储结构两个层次的描述。 逻辑结构 描述数据逻辑关系的一种方式,与数据的存储无关。逻辑结构中数据元素之间的关系主要分为四种:集合结构、线性结构、树结构、图结构。所有的数据结构在逻辑上都可以用这四种中的一种。 存储结构 数据和数据元素逻辑关系的存储对象,也被称为物理结构。通常逻辑结构包含两种,链式存储和顺序存储。 顺序存储 数据元素存储在一块连续的内存空间上,例如数组,就是一块连续的空间。 链式存储 数据存储不一定在一块连续的内存空间上,例如单链表。 数据类型 是一组值的集合和定义在这个集合上的操作的总称。 抽象数据类型 由用户定义的表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称,具体包括三部分,数据对象、数据对象上关系的集合以及对数据对象基本操作的集合。 抽象数据类型有自己的定义格式: 1ADT 抽象数据对象名 {2 数据对象:(数据对象的定义)3 数据关系:(数据关系的定义)4 基本操作:(基本操作的定义)5} 算法与数据结构 算法

《数据结构与算法》—— O(3N)=O(N) ?

邮差的信 提交于 2020-03-01 21:44:26
上帝的磨盘转动很慢,但是却磨得很细。 ——毛姆 本文已经收录至我的GitHub,欢迎大家踊跃star 和 issues。 https://github.com/midou-tech/articles 数据结构的基本概念 数据结构 相互之间存在一种或多种特定关系的数据元素的集合,我总结一下就是描述数据关系的一种载体。 数据结构包括逻辑结构和存储结构两个层次的描述。 逻辑结构 描述数据逻辑关系的一种方式,与数据的存储无关。逻辑结构中数据元素之间的关系主要分为四种:集合结构、线性结构、树结构、图结构。所有的数据结构在逻辑上都可以用这四种中的一种。 存储结构 数据和数据元素逻辑关系的存储对象,也被称为物理结构。通常逻辑结构包含两种,链式存储和顺序存储。 顺序存储 数据元素存储在一块连续的内存空间上,例如数组,就是一块连续的空间。 链式存储 数据存储不一定在一块连续的内存空间上,例如单链表。 数据类型 是一组值的集合和定义在这个集合上的操作的总称。 抽象数据类型 由用户定义的表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称,具体包括三部分,数据对象、数据对象上关系的集合以及对数据对象基本操作的集合。 抽象数据类型有自己的定义格式: 1ADT 抽象数据对象名 {2 数据对象:(数据对象的定义)3 数据关系:(数据关系的定义)4 基本操作:(基本操作的定义)5} 算法与数据结构 算法