1.归并排序
思想:分治,将数组分成小部分,每部分排序后合并成一个完整的有序数组,可以采用递归实现,递归深度log2n。
def merge(left,right): #两个有序数组的合并
res = [] #存放排序结果
while len(left) >0 and len(right) >0: #若两数组均不为空,则拿第一个元素依次比较,较小的从数组中弹出并放入res中
if left[0] <= right[0]:
res.append(left.pop(0))
else:
res.append(right.pop(0))
if len(left) == 0: #若其中一个数组放完了为空,则将剩余另一个数组直接放入res中即可
res.extend(right)
if len(right) == 0:
res.extend(left)
return res
def merge_sort(list): #分治
if len(list) == 1: #递归的出口,分到仅有一个元素
return list
else:
length = len(list) #将大数组一分为二
mid = length//2
list1 = list[:mid]
list2 = list[mid:]
left = merge_sort(list1) #只要分过数组长度不为一就继续递归调用去分
right = merge_sort(list2)
return merge(left,right) #合并
小结:归并排序是稳定的,利用完全二叉树的特性,每次合并操作的时间复杂度为O(n),二叉树深度为log2n,总的时间复杂度为O(nlogn),且最好最坏情况下复杂度一样。
2.快速排序
思路:“二分”思想,选择一个基准数,将比基准数小的都放他左边,比基准数大的都放他右边,递归的完成排序。
def quick_sort(list):
if not list:
return []
pivot = list[0]
left = quick_sort([x for x in list[1: ] if x < pivot])
right = quick_sort([x for x in list[1: ] if x >= pivot])
return left + [pivot] + right
小结:快排是一种不稳定的排序,最好情况是基准选择合适,每次都能均匀划分数组,时间复杂度是O(nlogn),最坏情况是基准元素每次均为最大或最小元素,则所有的数都划分到一个数组里了,时间复杂度为O(n^2)