开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第29天,点击查看活动详情
前言
本文主要介绍时间复杂度的基本概念以及场景算法的时间复杂度。
时间复杂度是用来描述发生了多少次常数操作的指标。
常数操作
如果某个操作跟数量的大小没有关系,每次都是固定时间的操作,这种操作叫做常数操作。
比如,1 + 1、10000 + 10000 、a + b,这些操作经历的过程都是一样的,都是加法操作,这个操作时间是固定的,所以这个加法操作就是常数操作。
再比如,有一个长度为10000的数组,从数组中取出第10位元素和取出1000位元素,这两个操作的时间也是大致一致的,这种操作也叫做常数操作。
在执行某一个方法时,执行一行代码,如果这行代码的执行时间是固定的,那么这行代码就为常数操作;如果这行代码的执行时间跟数据量有关系,那么这行代码就不是常数操作。
时间复杂度
以冒泡排序为例,假如有一个长度为8的数组,在执行冒泡排序时过程如下:
第1轮,第0位置和第1位置的数据相比较,如果前面比后面大,就进行交换;第1位置和第2位置比较,如果前面比后面大,就进行交换;以此类推,第1轮结束后,最大值就来到了第7位置。
第2轮,第0位置和第1位置的数据相比较,如果前面比后面大,就进行交换;第1位置和第2位置比较,如果前面比后面大,就进行交换;以此类推,第1轮结束后,最大值就来到了第6位置。
以此类推,直到整个数组是有序的。
冒泡排序时间复杂度
那么,冒泡排序的时间复杂度是如何计算的呢?
相邻两个元素比较,这个操作每次都是一样的,是常数时间的操作,记为A操作。
对于冒泡排序,第1轮进行了7次比较操作,第2轮进行了6次比较操作,第3轮进行了5次比较操作,...。
这些操作是等差数列,等差数列公式为:
Sn = na1 + * d
其中,a1和d都是常数操作。
对公式化简一下就是:
Sn = - ( - a1)n
时间复杂度就是整个表达式中最高阶项,用O表示。也就是说时间复杂度不关心低阶项,也不关心常数项,只关心最高阶项。
为什么只关心最高阶项?因为当数据量足够大时,低阶项和常数项和最高阶项比起来太微不足道了。
比如冒泡排序的时间复杂度为O(n2)。
冒泡排序的表达式可以表示为a*n2 + b * n + c, 其中a、b、c都为常数。
在估算时间复杂度时,要按照最差的情况来进行估算。
常数的时间复杂度为O(1)。
时间复杂度排序
常见的算法时间复杂度由小到大依次为:Ο(1)<Ο(logN)<Ο(N)<Ο(NlogN)<Ο(N2)<Ο(N3)< Ο(Nk) < Ο(2N) < Ο(3N) < Ο(kN) < Ο(N!)。
常见排序算法时间复杂度
| 排序算法 | 时间复杂度 |
|---|---|
| 选择排序 | Ο(N2) |
| 插入排序 | Ο(N2) |
| 冒泡排序 | Ο(N2) |
| 希尔排序 | Ο(Ns) 1<s<2 |
| 快速排序 | Ο(N2) |
| 堆排序 | Ο(NlogN) |
| 归并排序 | Ο(NlogN) |