-
算法:解决问题的方法和步骤
-
评价算法的好坏:渐近时间复杂度(运行时间) 和渐近空间复杂度(运行次数)。
-
渐近时间复杂度的大O标记:
- - 常量时间复杂度 - 布隆过滤器 / 哈希存储
- - 对数时间复杂度 - 折半查找(二分查找)
- - 线性时间复杂度 - 顺序查找 / 计数排序
- - 对数线性时间复杂度 - 高级排序算法(归并排序、快速排序)
- - 平方时间复杂度 - 简单排序算法(选择排序、插入排序、冒泡排序)
- - 立方时间复杂度 - Floyd算法 / 矩阵乘法运算
- - 几何级数时间复杂度 - 汉诺塔
- - 阶乘时间复杂度 - 旅行经销商问题 - NPC
快速排序
运用分治的思想 即将一个复杂问题不断拆解为简单的问题
如图:
代码示例
"""
快速排序 - 选择枢轴对元素进行划分,左边都比枢轴小右边都比枢轴大
"""
test_list=[5,8,31,476,7,3,6,94,12,76,48,1,5,7,6,9,5,45878,31,846,0]
def quick_sort(alist,comp= lambda x,y :x<=y):
alist = alist[:]
start =0 # 起始位置索引
end = len(alist)-1 # 结束位置索引
_quick_sort(alist,start,end,comp)
return alist
def _quick_sort(alist,start,end,comp):
if start < end:
posvit = _pos(alist,start,end,comp)
# 调用闭包让问题无线拆解
_quick_sort(alist,start,posvit-1,comp)
_quick_sort(alist,posvit+1,end,comp)
def _pos(alist,start,end,comp):
postvit = alist[end]
i = start -1
for j in range(start,end):
if comp(alist[j],postvit):
i+=1
alist[i],alist[j] = alist[j],alist[i]
alist[i + 1], alist[end] = alist[end], alist[i + 1] # 调用局部变量 排序
return i+1
dd=quick_sort(test_list)
dd
out:[0, 1, 3, 5, 5, 5, 6, 6, 7, 7, 8, 9, 12, 31, 31, 48, 76, 94, 476, 846, 45878]
def bubble_sort(items, comp=lambda x, y: x > y):
"""冒泡排序"""
items = items[:]
for i in range(len(items) - 1):
swapped = False
for j in range(len(items) - 1 - i):
if comp(items[j], items[j + 1]):
items[j], items[j + 1] = items[j + 1], items[j]
swapped = True
if not swapped:
break
return items
def bubble_sort(items, comp=lambda x, y: x > y):
"""搅拌排序(冒泡排序升级版)"""
items = items[:]
for i in range(len(items) - 1):
swapped = False
for j in range(len(items) - 1 - i):
if comp(items[j], items[j + 1]):
items[j], items[j + 1] = items[j + 1], items[j]
swapped = True
if swapped:
swapped = False
for j in range(len(items) - 2 - i, i, -1):
if comp(items[j - 1], items[j]):
items[j], items[j - 1] = items[j - 1], items[j]
swapped = True
if not swapped:
break
return items
归并排序
def merge(items1, items2, comp=lambda x, y: x < y):
"""合并(将两个有序的列表合并成一个有序的列表)"""
items = []
index1, index2 = 0, 0
while index1 < len(items1) and index2 < len(items2):
if comp(items1[index1], items2[index2]):
items.append(items1[index1])
index1 += 1
else:
items.append(items2[index2])
index2 += 1
items += items1[index1:]
items += items2[index2:]
return items
def merge_sort(items, comp=lambda x, y: x < y):
return _merge_sort(list(items), comp)
def _merge_sort(items, comp):
"""归并排序"""
if len(items) < 2:
return items
mid = len(items) // 2
left = _merge_sort(items[:mid], comp)
right = _merge_sort(items[mid:], comp)
return merge(left, right, comp)
def select_sort(items, comp=lambda x, y: x < y):
"""简单选择排序"""
items = items[:]
for i in range(len(items) - 1):
min_index = i
for j in range(i + 1, len(items)):
if comp(items[j], items[min_index]):
min_index = j
items[i], items[min_index] = items[min_index], items[i]
return items