1 插入排序(Insert Sort)
1.1 插入排序原理
最坏时间:输入逆序。
比较次数:(n+2)(n-1)/2
移动次数:(n+4)(n-1)/2
平均时间:输入规模为n时,所有可能输入的期望时间。换一种说法,每种输入的运行时间,乘以那种输入出现的概率,是一种加权平均。
如何知道某种输入出现的概率?
通过一个有关输入的统计分布的假设。常见的假设就是,所有输入都是以等可能的方式出现的,即均匀分布。
最少时间:输入正序。
比较次数:n-1
移动次数:0
插入排序快不快?当n很小的时候,挺快,当n很大,就会很慢,通常n<=8。
1.2 python 实现
def insert_sort(A):
n = len(A)
for i in range(1, n):
key = A[i]
j = i - 1
while j >= 0 and A[j] > key:
A[j + 1] = A[j]
j -= 1
A[j + 1] = key
return A
def insert_sort1(A):
n = len(A)
for i in range(1, n):
for j in range(0, i):
if A[i] < A[j]:
tmp = A[j]
A[j] = A[i]
A[i] = tmp
return A
if __name__ == '__main__':
print(insert_sort([4, 3, 123, 12, 2, 5, 0, 88]))
2 归并排序(Merge Sort)
分治法:将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后在阿合并这些子问题的解来建立原问题的解。
2.1 算法原理
伪代码如下:
2.2 算法分析
总时间:
- 如果n=1, 排序完成
- Merge_Sort: 递归排序,
和
- Merge: 合并连个已经排好序的列表
第一步所需时间,
第二步所需时间
第三部所需时间
所以,归并排序最坏情况下运行时间的递归式:
因 , 递归式可重写为:
求解递归式:
递归树具有层,每层的代价均为cn , 所以总代价为
, 忽略低价项和常量c ,期望的结果为
。
2.3 python 实现
def MergeSort(lists):
if len(lists) <= 1:
return lists
middle = len(lists)//2
left = MergeSort(lists[:middle])
right = MergeSort(lists[middle:])
return merge(left, right)
def merge(a, b):
c = []
h = j = 0
while j < len(a) and h < len(b):
if a[j] < b[h]:
c.append(a[j])
j += 1
else:
c.append(b[h])
h += 1
if j == len(a):
for i in b[h:]:
c.append(i)
else:
for i in a[j:]:
c.append(i)
return c
if __name__ == '__main__':
a = [4, 7, 8, 3, 5, 9]
print(MergeSort(a))
3 算法分析
运行时间依赖于输入,比如输入的个数,输入的排序情况。
渐进分析的基本思路是,忽略依赖于机器的常量,不去检查实际的运行时间,而是关注运行时间的增长。弃低阶项和常数因子。