算法笔记 7 归并排序和快速排序
Posted 珷玞的日常
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法笔记 7 归并排序和快速排序相关的知识,希望对你有一定的参考价值。
上一部分笔记是时间复杂度为 O(N^2),比较高,适合小规模数据的排序。今天看两种时间复杂度为 O(nlogn),归并排序和快速排序。
归并排序
归并排序就是一个典型的分而治之思想的算法,核心思想:将序列分为前后两部分,对前后两部分分别排序,然后合并这两部分,得到最后结果。
根据归并的核心思想,我们其实是将排序问题分解为两个子问题:前半部分排序,后半部分排序。这两个子问题又进行分解,最后分解为单独元素之后,进行归并,这也是排序的过程,最后得到结果。
由于归并使用分而治之的思想,所以我们使用递归的方法来实现代码。具体如下:
# 归并排序
def mergeSort(l):
if len(l) <= 1:
return l
else:
return mergeSortRecursion(l)
# 递归部分,主体部分就是不停的分割合并
def mergeSortRecursion(l):
head = 0
tail = len(l) - 1
if len(l) <= 1:
return l
else:
m = int(len(l)/2)
l1 = mergeSortRecursion(l[head:m])
l2 = mergeSortRecursion(l[m:tail+1])
result = merge(l1,l2)
return result
# 合并函数,进行两个数组之间的合并
def merge(l,s):
i = 0
j = 0
result = []
while i<len(l) and j<len(s):
# 如果 l 的最后一个元素小于 s 的第一个元素,因为 l s 都是有序的,所以直接拼接就可以了
if l[-1] <= s[j]:
break
if l[i] <= s[j]:
result.append(l[i])
i += 1
else:
result.append(s[j])
j += 1
result += l[i:]
result += s[j:]
return result
l = [6,5,4,3,2,1]
print([i for i in mergeSort(l)])
分析
归并排序是稳定的排序算法么?
稳定取决于 merge 函数的比较,我们代码中是小于等于的时候,result 添加 l[i],所以 l 中的元素始终在 s 的元素前边,所以是稳定的。
归并排序时间复杂度?
时间复杂度为 O(nlogn),由于归并排序的执行效率与要排序的原始数组的有序程度无关,所以时间复杂度很稳定。
快速排序
快速排序也是分而治之思想的一种典型的算法。基本思想:在序列中随意找一个元素为基准,然后遍历其他数据,小于的放在左边,大于的放在右边。
代码实现:
def quick_sort(array, l, r):
if l < r:
q = partition(array, l, r)
quick_sort(array, l, q - 1)
quick_sort(array, q + 1, r)
def partition(array, l, r):
x = array[r]
i = l - 1
for j in range(l, r):
if array[j] <= x:
i += 1
array[i], array[j] = array[j], array[i]
array[i + 1], array[r] = array[r], array[i + 1]
return i + 1
分析
快速排序是一种稳定的、原地排序
快速排序的时间复杂度
快速排序的时间复杂度为 O(nlogn)
以上是关于算法笔记 7 归并排序和快速排序的主要内容,如果未能解决你的问题,请参考以下文章