数据结构与算法中的时间复杂度详解
最近在看数据结构与算法方面的书,因此打算在看书的过程中更新一些学到的知识。尽管我不希望讲解枯燥的理论概念,但是我还是想简单的说一下什么是数据结构什么是算法。
数据结构指的是一组数据的存储结构,算法指的是操作数据的一组方法。数据结构是为算法服务的,算法需要在特定的数据结构上进行操作。下图是数据结构与算法中涉及到的知识点。
今天着重更新的是算法中的时间与空间复杂度,一般地,我们将算法的复杂度指的是时间复杂度,是用于衡量算法效率的一个关键指标。
算法的时间复杂度的定义是:在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级,记做:T(n)=O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,乘坐算法的渐近时间复杂度,简称为时间复杂度。
下面通过着重讲解常见的几种时间复杂度。
1、常数阶:一般情况下,只要算法中不存在循环语句、递归语句等,即便有成千上万行代码,其时间复杂度也是O(1)
sum=0;n=100 #执行一次
sum=(1+n)*n/2 #执行一次
print(sum) #执行一次
2、线性阶
sum=0;n=100 #执行一次
for i in range(1,n+1): #执行一次
sum+=i #执行n次
print(sum) #执行一次
3、对数阶。log(n),对数是可以相互转换的
sum=0;n=100 #执行一次
i=1 #执行一次
while i <=n: #执行一次
i=i*2 #执行log2(n)次
print(sum) #执行一次
下面这个代码也是对数阶,因为log3(n)=log3(2)*log2(n)
i=1
while (i <= n) {
i = i * 3
}
4、平方阶
sum=0;n=100;num=0 #执行一次
for i in range(1,n+1): #执行一次
for j in range(1,n+1): #执行一次
num+=1 #执行n**2次
sum++num #执行n**2次
print(sum) #执行一次
一般地,常见的时间复杂度如下表所示。
常用的时间复杂度所耗费的时间从小到大依次是:
0(1) < O(logn) < O(n) < O(nlogn) < 0(n2) < 0(n3) < 0(2" ) < O(n!) < O(n")
上面讲解了常见的复杂度 分析方法,但是对于一些复杂的例子还是需要进一步分析。下面介绍另外的四个知识点:最好情况时间复杂度、最坏情况时间复杂度、平均情况时间复杂度、均摊时间复杂度。
// n 表示数组 array 的长度
int find(int[] array, int n, int x) {
int i = 0;
int pos = -1;
for (; i < n; ++i) {
if (array[i] == x) pos = i;
}
return pos;
}
下面是用python实现的各个复杂度耗时的图,代码和图如下所示。
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x=np.linspace(1,3,100)
ax.plot(x, x/x, label="y =1")
ax.plot(x, np.log2(np.abs(x)), label="y = log(x)")
ax.plot(x, x, label="y = x")
ax.plot(x, x*np.log2(np.abs(x)), label="y = xlog(x)")
ax.plot(x, x**2, label="y = x**2")
ax.plot(x, x**3, label="y = x**3")
ax.plot(x, 2**x, label="y = 2**x")
ax.legend(loc=2)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('算法时间对比')
plt.show()