算法笔记 7 归并排序和快速排序

Posted 珷玞的日常

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法笔记 7 归并排序和快速排序相关的知识,希望对你有一定的参考价值。

上一部分笔记是时间复杂度为 O(N^2),比较高,适合小规模数据的排序。今天看两种时间复杂度为 O(nlogn),归并排序和快速排序。

归并排序

归并排序就是一个典型的分而治之思想的算法,核心思想:将序列分为前后两部分,对前后两部分分别排序,然后合并这两部分,得到最后结果。

根据归并的核心思想,我们其实是将排序问题分解为两个子问题:前半部分排序,后半部分排序。这两个子问题又进行分解,最后分解为单独元素之后,进行归并,这也是排序的过程,最后得到结果。

由于归并使用分而治之的思想,所以我们使用递归的方法来实现代码。具体如下:

 
   
   
 
  1. # 归并排序

  2. def mergeSort(l):

  3.    if len(l) <= 1:

  4.        return l

  5.    else:

  6.        return mergeSortRecursion(l)

  7. # 递归部分,主体部分就是不停的分割合并

  8. def mergeSortRecursion(l):

  9.    head = 0

  10.    tail = len(l) - 1

  11.    if len(l) <= 1:

  12.        return l

  13.    else:

  14.        m = int(len(l)/2)

  15.        l1 = mergeSortRecursion(l[head:m])

  16.        l2 = mergeSortRecursion(l[m:tail+1])

  17.        result = merge(l1,l2)

  18.    return result

  19. # 合并函数,进行两个数组之间的合并

  20. def merge(l,s):

  21.    i = 0

  22.    j = 0

  23.    result = []

  24.    while i<len(l) and j<len(s):

  25.        # 如果 l 的最后一个元素小于 s 的第一个元素,因为 l s 都是有序的,所以直接拼接就可以了

  26.        if l[-1] <= s[j]:

  27.            break

  28.        if l[i] <= s[j]:

  29.            result.append(l[i])

  30.            i += 1

  31.        else:

  32.            result.append(s[j])

  33.            j += 1

  34.    result += l[i:]

  35.    result += s[j:]

  36.    return result

  37. l = [6,5,4,3,2,1]

  38. print([i for i in mergeSort(l)])

分析

  1. 归并排序是稳定的排序算法么?

稳定取决于 merge 函数的比较,我们代码中是小于等于的时候,result 添加 l[i],所以 l 中的元素始终在 s 的元素前边,所以是稳定的。

  1. 归并排序时间复杂度?

时间复杂度为 O(nlogn),由于归并排序的执行效率与要排序的原始数组的有序程度无关,所以时间复杂度很稳定。

快速排序

快速排序也是分而治之思想的一种典型的算法。基本思想:在序列中随意找一个元素为基准,然后遍历其他数据,小于的放在左边,大于的放在右边。

代码实现:

 
   
   
 
  1. def quick_sort(array, l, r):

  2.    if l < r:

  3.        q = partition(array, l, r)

  4.        quick_sort(array, l, q - 1)

  5.        quick_sort(array, q + 1, r)

  6. def partition(array, l, r):

  7.    x = array[r]

  8.    i = l - 1

  9.    for j in range(l, r):

  10.        if array[j] <= x:

  11.            i += 1

  12.            array[i], array[j] = array[j], array[i]

  13.    array[i + 1], array[r] = array[r], array[i + 1]

  14.    return i + 1

分析

  1. 快速排序是一种稳定的、原地排序

  2. 快速排序的时间复杂度

快速排序的时间复杂度为 O(nlogn)


以上是关于算法笔记 7 归并排序和快速排序的主要内容,如果未能解决你的问题,请参考以下文章

重学数据结构和算法之归并排序快速排序

JavaScript算法(归并排序与快速排序)

算法笔记

归并排序和快速排序

学习数据结构笔记====>不同的排序算法(Sort Algorithm)[冒泡,选择,插入,快速,希尔,基数,归并]

算法浅谈——分治算法与归并快速排序(附代码和动图演示)