时间复杂度和空间复杂度是衡量一个算法的两个重要指标,用于表示算法的最差状态所需的时间增长量和所需辅助空间.

接下来用我之前所写的冒泡排序作为例子来讨论:

def bubble_sort(arr):
length = len(arr)
# 第一级遍历
for index in range(length):
# 第二级遍历
for j in range(1, length - index):
if arr[j - 1] > arr[j]:
# 交换两者数据,这里没用temp是因为python 特性元组。
arr[j - 1], arr[j] = arr[j], arr[j - 1]
return arr

冒泡算法最坏情况(逆序)的运行时间和长度有2次线性关系,具体算式如下:

T(n) = a * (n*(n-1)+(n-1)*(n-2)+...+2*1)+C = 4n * ( n/2 ) + C

其中 C 为常数运算次数 ,比如调用函数,设置长度, a 为循环体中进行的操作数.

衡量一个算法的运行时间主要是看其在长时间运行中的表现情况,所以在计算时间复杂度的时候,只需考虑最高次幂的项.

在冒泡算法中时间开销最大的项为 an^2 从这里我们就可已得出冒泡算法的排序长度和运行时间成二次曲线.

而在表达时间复杂度时,为了只关注代码运算时间的增长率,还忽略掉最高项的系数,由此可得时间复杂度为 O(n^2).

那么冒泡算法的空间复杂度呢?

是 O(1) ,在这个Python范例中由于使用了元组,所以我们利用到的额外空间只有 length,也就是说不管如何进行运算,这个算法占用的空间永远是常数空间.

空间复杂度又被称作辅助空间,与时间复杂度一样,空间复杂度同样只考虑所占空间的增长率.

在基础算法中,我们常常会使用辅助空间来节约算法的运行时间,比如归并排序:

# 递归法
def merge_sort(list):
# 认为长度不大于1的数列是有序的
if len(list) <= 1:
return list
# 二分列表
middle = len(list) // 2
left = merge_sort(list[:middle])
right = merge_sort(list[middle:])
# 最后一次合并
return merge(left, right)
# 合并
def merge(left, right):
l,r=0,0
result=[]
while l
if left[l] 
result.append(left[l])
l+=1
else:
result.append(right[r])
r +=1
reslut +=left[l:]
result+=right[r:]
return result

就利用了 O(n) 的辅助空间来进行排序.

对着两种排序算法有疑问可以看我之前的文章.

有人认为基本算法并没有什么意义,其实不然,这些基础的算法和数据结构将会是减少用户等待时间的磨刀石.