数据结构 : 数组 / 链表 / 二叉排序树增删改查的时间复杂度解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 数据结构 : 数组 / 链表 / 二叉排序树增删改查的时间复杂度解析

我们先看一下时间复杂度的概念:


   在计算机科学中,算法的时间复杂度(Time complexity)是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的字符串的长度的函数。

记作: T(n) = O(f(n))。它表示随着 输入大小n 的增大,算法执行需要的时间的增长速度可以用 f(n) 来描述。


接下来我们对比一下数组 / 链表 / 二叉树增删改查的时间复杂度


一.数组


数组长度设为n

1.正常数组:


增改查:

既然知道数值对应的下标,那么我们要想找到一个数组中的数,只需要锁定其下标,对它进行增改查操作即可.所以这是一步锁定的操作.

则这种情况下增改查的时间复杂度是 O(1).


删:

一步锁定找到想要删除的数值,进行删除,然后需要移动删除部分后面的数值,如果该数值在数组头部,则需要移动n次,若在尾部,则无需移动,取一个平均值则需要n/2次,忽略常数,所以删操作的时间复杂度是 O(n).


2.无下标数组:


不知道数值的对应下标的数组,我们简称为无下标的数组,不知道所要操作的数值在数组的什么地方,这就需要我们去数组遍历寻找,然后进行操作.


增:

数组是地址连续存储的,所以对数组进行增操作,只要在数组尾部增加即可,一步到位,所以增操作的时间复杂度是 O(1).


删:

要遍历找到想要删除的数值,进行删除,如果该数值在数组头部,则需要遍历一次,若在尾部,则需要遍历n次,取一个平均值则需要遍历n/2次,忽略常数,所以删操作的时间复杂度是 O(n).


改:

改操作同删除操作类似,要遍历找到想要更改的数值,进行更改,所以改操作的时间复杂度是 O(n).


查:

查操作也同上,时间复杂度是 O(n).


3.有序无下标数组:


查:

这里我们先说查操作,计算机在进行操作时,会选择使用最优的方法解决问题,我们这里的数组是有序的,所以使用 二分查找 比遍历查找更快,其平均查找次数是log2n.

实际上由于所有的对数都和其他对数成比例(从底数位2转换到底数位10需乘以3.332),我们可以将这个为常数的底数也可忽略。由此不必指定底数:时间复杂度是 log(n).


增:

针对有序无下标的数组,不能随意在尾部添加数据,应该找到数据适合添加的位置,平均查找次数是平均查找次数是log2n,找到该位置后,还要将插入位置后面的数组进行后移操作,平均移动次数也是n/2,相加则平均进行n/2+log2n次操作,时间复杂度取最大值,则增操作的时间复杂度是 O(n).


删:

删操作同样针对有序无下标的数组,要遍历找到想要删除的数值,进行删除,平均查找次数是log2n,找到该位置后删除,还要将删除位置后面的数组进行前移操作,平均移动次数是n/2,同理删操作的时间复杂度是 O(n).


改:

改操作同删除操作类似,要遍历找到想要更改的数值,进行更改,平均查找次数是log2n,还要将该更改的数找到合适的位置移动排序,平均查找次数是n/2,所以改操作的时间复杂度是 O(n).


二.链表

设链表长度为n


1.单向无序链表:


增:

链表是通过记录头部地址来进行寻找后面数值的,所以需要遍历链表操作,如果在头部增,只需要查找一次,时间复杂度是 O(1),在尾部增需要查找n次,时间复杂度是 O(n).


删:

要遍历找到想要删除的数值,进行删除,对于链表,我们没法使用二分查找,只能遍历查找,找到该节点后删除,平均查找次数是n/2,时间复杂度是 O(n).


改:

要遍历找到想要更改的数值,同样只能遍历查找,平均查找次数是n/2,时间复杂度是 O(n).


查:

要遍历查找,同样只能遍历查找,平均查找次数是n/2,时间复杂度是 O(n).


2.单向有序链表:


增:

针对有序链表操作,需要保持其有序的原则,遍历链表找到该数值所在节点可以增加的位置,平均查找次数是n/2,时间复杂度是 O(n).


删:

通过遍历查找,找到该节点后删除,平均查找次数是n/2,时间复杂度是 O(n).


改:

通过遍历查找,找到想要更改的数值,同样只能遍历查找,平均查找次数是n/2,然后需要根据有序原则,为该节点寻找适合的位置进行移动,平均查找时间是n/2,时间复杂度是 O(n).


查:

要遍历查找,同样只能遍历查找,平均查找次数是n/2,时间复杂度是 O(n).


三. 二叉排序树:


二叉排序树又称二叉查找树,它或是一棵空的二叉树,或是具有下列性质的二叉树:


若它的左子树不空,则左子树上所有节点的值均小于根节点的值

若它的右子树不空,则右子树上所有节点的值均大于根节点的值

它的左右子树也都是二叉排序树


查:

给定值的比较次数等于给定值节点在二叉排序树中的层数。如果二叉排序树是平衡的,则n个节点的二叉排序树的高度为log2n +1,其查找效率为O(log2n),近似于折半查找。如果二叉排序树完全不平衡,则其深度可达到n,查找效率为O(n),退化为顺序查找。一般的,二叉排序树的查找性能在O(log2n)到O(n)之间。因此,为了获得较好的查找性能,就要构造一棵平衡的二叉排序树。


增/删/改:

同理如查


四.总结


该表时间复杂度是根据已知数值,对数组 / 链表 / 二叉树进行操作的总结:


数据结构
正常数组 O(1) O(n) O(1) O(1)
无下标数组 O(1) O(n) O(n) O(n)
有序无下标数组 O(n) O(n) O(n) log(n)
单向无序链表 O(n) O(n) O(n) O(n)
单向有序链表 O(n) O(n) O(n) O(n)
双向无序链表 O(n) O(n) O(n) O(n)
双向有序链表 O(n) O(n) O(n) O(n)
二叉树(最好情况) O(logn) O(logn) O(logn) O(logn)
二叉树(一般情况) O(logn)~O(n) O(logn)~O(n) O(logn)~O(n) O(logn)~O(n)
二叉树(最坏情况) O(n) O(n) O(n) O(n)


目录
相关文章
|
16天前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
44 4
|
18天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
18天前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
30天前
|
人工智能 前端开发 JavaScript
拿下奇怪的前端报错(一):报错信息是一个看不懂的数字数组Buffer(475) [Uint8Array],让AI大模型帮忙解析
本文介绍了前端开发中遇到的奇怪报错问题,特别是当错误信息不明确时的处理方法。作者分享了自己通过还原代码、试错等方式解决问题的经验,并以一个Vue3+TypeScript项目的构建失败为例,详细解析了如何从错误信息中定位问题,最终通过解读错误信息中的ASCII码找到了具体的错误文件。文章强调了基础知识的重要性,并鼓励读者遇到类似问题时不要慌张,耐心分析。
|
16天前
|
C语言
【数据结构】双向带头循环链表(c语言)(附源码)
本文介绍了双向带头循环链表的概念和实现。双向带头循环链表具有三个关键点:双向、带头和循环。与单链表相比,它的头插、尾插、头删、尾删等操作的时间复杂度均为O(1),提高了运行效率。文章详细讲解了链表的结构定义、方法声明和实现,包括创建新节点、初始化、打印、判断是否为空、插入和删除节点等操作。最后提供了完整的代码示例。
37 0
|
1月前
|
存储
[数据结构] -- 双向循环链表
[数据结构] -- 双向循环链表
21 0
|
1月前
|
算法
[数据结构] -- 时间复杂度和空间复杂度
[数据结构] -- 时间复杂度和空间复杂度
15 0
|
1月前
|
存储
探索数据结构:便捷的双向链表
探索数据结构:便捷的双向链表
|
15天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
90 9
|
6天前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
15 1

推荐镜像

更多