快速排序

描述

快速排序是一种基于分治策略的排序方法。对n个数组排序,最坏情况的运行时间为 O(n2) ,期望的运行时间为 O(nlg(n)) ,由于其平均性能较好,通常用于排序的最佳的使用选择。
分治策略是一类算法设计的技术,把问题分成若干部分,递归求解每一部分的解,然后合并解集合构成全局解。
对于数组 A[p...r]

  • 分解,划分数组为 A[p...q1] A[q+1...r]
    其中 A[p...q1] 每个元素都 <=A(q) <script type="math/tex" id="MathJax-Element-502"><=A(q)</script>, A[q+1...r] 每个元素都 >=A(q)
  • 解决,递归,对子数组 A[p...q1] A[q+1...r] 分别进行排序。
  • 合并

伪代码

quicksort(A, p, r)
if p < r
q = partition(A, q, r)
quicksort(A, p, q - 1)
quicksort(A, q + 1, r)

举例与代码

下面以例子说明partition函数实现。
例如数组A[13, 19, 9, 5, 12, 8, 7, 4, 21, 2, 6, 1]。
设定基准值,一般取第一项,这里为13。
就地排序,设法使13左侧的值都小于或等于13,13右侧的值都大于或等于13。
返回13最终所在位置,即q。
下面是一种实现方法:

def partition(A, p, r):
    i = p
    j = r
    key = A[i]

    while(i < j):

        while (i < j and A[j] >= key):
            j = j - 1

        A[i] = A[j]

        while (i < j and A[i] <= key):
            i = i + 1

        A[j] = A[i]
        j = j - 1

    A[i] = key

    return i

每次迭代结果如下:

[q:9 p:0 r:11]   [1, 6, 9, 5, 12, 8, 7, 4, 2, 13, 21, 19]
[q:0 p:0 r:8]    [1, 6, 9, 5, 12, 8, 7, 4, 2, 13, 21, 19]
[q:4 p:1 r:8]    [1, 2, 4, 5, 6, 8, 7, 12, 9, 13, 21, 19]
[q:1 p:1 r:3]    [1, 2, 4, 5, 6, 8, 7, 12, 9, 13, 21, 19]
[q:2 p:2 r:3]    [1, 2, 4, 5, 6, 8, 7, 12, 9, 13, 21, 19]
[q:6 p:5 r:8]    [1, 2, 4, 5, 6, 7, 8, 12, 9, 13, 21, 19]
[q:8 p:7 r:8]    [1, 2, 4, 5, 6, 7, 8, 9, 12, 13, 21, 19]
[q:11 p:10 r:11] [1, 2, 4, 5, 6, 7, 8, 9, 12, 13, 19, 21]

算法导论中实现方式如下:

def EXCHAGE(A, i, j):
    if (A[i] == A[j]):
        return
    A[i] = A[i] ^ A[j]
    A[j] = A[i] ^ A[j]
    A[i] = A[i] ^ A[j]

def partition_(A, p, r):
    key = A[r]
    i = p - 1
    for j in range(p, r):
        if A[j] <= key:
            i = i + 1
            EXCHAGE(A, i, j)

    EXCHAGE(A, i + 1, r)

    return i + 1

运行时间比较

import numpy as np
import time as t

array = np.random.randint(1000000, size=100000)

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

    q = partition(array, p, r)   
    quicksort(A, p, q - 1)
    quicksort(A, q + 1, r)

t_s = t.time()
quicksort(array, 0, len(array) - 1)
print((t.time() - t_s) * 1000)

partition耗时504.5ms
partition_耗时1174.6ms

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值