文章目录
时间复杂度
- O( c ) 常量时间复杂度 - 布隆过滤器 / 哈希存储
- O(log2n) 对数时间复杂度 - 折半查找(二分查找)
- O(n) 线性时间复杂度 - 顺序查找 / 计数排序
- O(n*log2n) 对数线性时间复杂度 - 高级排序算法(归并排序、快速排序)
- O(n2) 平方时间复杂度 - 简单排序算法(选择排序、插入排序、冒泡排序)
- O(n3) 立方时间复杂度 - Floyd算法 / 矩阵乘法运算
- O(2n) 几何级数时间复杂度 - 汉诺塔
- O(n!) 阶乘时间复杂度 - 旅行经销商问题 - NPC
排序算法
交换排序
冒泡排序
时间复杂度 O(n2),空间复杂度 O
(1),稳定排序算法。
def bubble_sort(alist):
'''冒泡排序'''
n = len(alist)
for i in range(n-1):
for j in range(n-i-1):
if alist[j] > alist[j+1]:
alist[j], alist[j+1] = alist[j+1], alist[j]
return alist
快速排序
时间复杂度 O(n*log2n), 空间复杂度 O(log2n),非稳定排序算法。
原理:从序列中找出一个基准元素(pivot),然后大于该元素的放到一边,小于该元素的放到另一边形成分区;然后在分别冲大小分区中再找基准再分别分出相对大小分区,这样递归的完成快速排序。
def quick_sort(alist):
'''快速排序'''
if len(alist) <= 1:
return alist
else:
# 设置基准元素为alist的第一个元素,也可以是其它
pivot = alist[0]
# 移除alist中的基准元素
alist.remove(pivot)
left_part, right_part = [], []
for num in alist:
if num <= pivot:
left_part.append(num)
else:
right_part.append(num)
return quick_sort(left_part) + [pivot] + quick_sort(right_part)
上面算法实现的快排在遍历数组时需要额外的空间,下面这种优化算法实现了原地排序。
def quick_sort_optimized(alist, start, end): # 注意不要让end溢出(end=len(alist)-1)
'''快速排序优化'''
if start >= end:
return
else:
# 选取基准元素pivot
pivot = alist[start]
# 定义两个指(low、high)针从列表两端读取数据
low = start
high = end
while low < high:
# 如果low与high未重合,high指向的元素不比基准元素小,则high向左移动
while low < high and pivot <= alist[high]:
high -= 1
# 当high指向的元素小于pivot时,将其放到low的位置上
alist[low] = alist[high]
# 如果low与high未重合,low指向的元素比基准元素大,则low向右移动
while low < high and pivot > alist[low]:
low += 1
# 当low指向的元素大于pivot时,将其放到high的位置上
alist[high] = alist[low]
# 退出循环后,low与high重合,此时所指位置为基准元素的正确位置
# 将基准元素放到该位置
alist[low] = pivot
quick_sort_optimized(alist