归并排序、快速排序

版权声明:Copyright (c) strongnine https://blog.csdn.net/weixin_39679367/article/details/84312016

这篇博客是对极客时间上王争课程 —— 数据结构与算法之美的个人学习总结。文章中的图出自课程中。我会对课程中的 Java 代码用 Python 来实现,所有的代码会放在我的 GitHub 上。


4. 归并排序(Merge Sort)

归并排序使用递推的方式来实现,把需要排序的数组逐步分成更小的部分,进行排序,然后再组合起来。由于是递推,最重要的是要建立递推公式:

看这里的递推公式:

递推公式
merge_sort(p...r) = merge(merge_sort(p...q), merge_sort(q+1...r))

终止条件
p >= r 不用再继续分解

递推如果看代码去理解的话会很复杂,但是建立了递推公式,按照公式来进行就会变得简单很多。这个公式就是把数组分为 p 到 q,q+1 到 r 两部分,对每一部分都进行同样的操作,直到不能再分。

按照递推公式来弄成代码就是:

# Copyright(c) strongnine

## 归并排序算法, A 是数组
def merge_sort(A):
    n = len(A)
    return merge_sort_c(A, 0, n - 1)

def merge_sort_c(A, p, r):
    ## 递归终止条件
    if p >= r:
        return

    ## 取 p 到 r 之间的中间位置 q
    q = (p + r) // 2
    ## 分治递归
    merge_sort_c(A, p, q)
    merge_sort_c(A, q+1, r)
    ## 将 A[p...q] 和 A[q+1...r] 合并为 A[p...r]
    A = merge(A, p, q, r)
    return A

def merge(A, p, q, r):
    i = p
    j = q + 1
    tmp = []
    while (i <= q) & (j <= r):
        if A[i] <= A[j]:
            tmp.append(A[i])
            i += 1
        else:
            tmp.append(A[j])
            j += 1


    ## 判断哪个子数组中有剩余的数据
    start = i
    end = q
    if j <= r:
        start = j
        end = r
    ## 将剩余的数据拷贝到临时数据 tmp
    while start <= end:
        tmp.append(A[start])
        start += 1

    return tmp


if __name__ == '__main__':
    A = [1, 5, 6, 2, 3, 4]
    B = [1, 2, 3, 5, 7, 8, 9, 11]
    A = merge_sort(A)
    B = merge_sort(B)
    print(A, B)

其中最重要的就是 merge_sort_c() 这个函数,它有个嵌套。

归并排序的过程分解如下:

在这里插入图片描述

归并排序是非原地的稳定的算法,时间复杂度 O(nlogn),空间复杂度 O(n)。

5. 快速排序(Quicksort)

快速排序简称快排,也是用的分治思想。递推公式:

递推公式:
quick_sort(p...r) = quick_sort(p...q-1) + quick_sort(q+1, r)

终止条件:
p >= r

代码:

扫描二维码关注公众号,回复: 4378269 查看本文章
# Copyright(c) strongnine

## 快速排序
def quick_sort(A):
    n = len(A)

    quick_sort_c(A, 0, n - 1)

    return A

def quick_sort_c(A, p, r):
    if p >= r:
        return

    ## 获取分区点
    q = partition(A, p, r)
    quick_sort_c(A, p, q - 1)
    quick_sort_c(A, q + 1, r)

    return A

def partition(A, p, r):
    pivot = A[r]
    i = p
    for j in range(p, r):
        if A[j] < pivot:
            A[i], A[j] = A[j], A[i]
            i += 1

    A[i], A[r] = A[r], A[i]

    return i


if __name__ == '__main__':
    A = [11, 8, 3, 9, 7, 1, 2, 5]
    A = quick_sort(A)
    print(A)

猜你喜欢

转载自blog.csdn.net/weixin_39679367/article/details/84312016