排序算法

快速排序

  快速排序在大多情况下的表现优异,其核心思想为分而治之。
  具体操作:对于一个长度为 n n n的数组 A A A,根据改变元素 x = A [ i ] x=A[i] x=A[i]的位置,使得数组 A A A满足:
* x x x左边的元素都不大于 x x x
* x x x右边的元素都不小于 x x x
  此时 x x x就位于数组排序完成后其应所在位置。然后对 x x x左右两侧进行递归操作即可完成排序。值得注意的是,通常将 x x x选定为数组靠中间的元素时效果较好。

def quick_sort(sequence):
    if len(sequence) == 1:
        return sequence
    elif len(sequence) == 0:
        return []
    mid = len(sequence) // 2
    sequence[0], sequence[mid] = sequence[mid], sequence[0]
    split = 1
    for ii in range(1, len(sequence)):
        if sequence[ii] < sequence[0]:
            sequence[ii], sequence[split] = sequence[split], sequence[ii]
            split += 1
    sequence[0], sequence[split - 1] = sequence[split - 1], sequence[0]
    left = quick_sort(sequence[:split - 1])
    right = quick_sort(sequence[split:])
    return left + [sequence[split - 1]] + right

  每层递归加起来相当于对于数组进行了一次扫描,共需进行 log ⁡ n \log{n} logn层递归,故时间复杂度为 n log ⁡ n n\log{n} nlogn;每层递归需常数个变量,故空间复杂度为 log ⁡ n \log{n} logn
  最佳运行时间为 n log ⁡ n n\log{n} nlogn;当所有的 x x x元素都需要放到当次递归数列后方时,有最差运行时间 n 2 n^2 n2

归并排序

  核心思想:分而治之。对于一个长度为 n n n的数组 A A A,进行以下操作:
* 将 A A A分为两个长度相等或相差一的新数组。
* 对每一个新数组进行归并排序。
* 将排序好的数组归并得到最终结果。

def merge_sort(sequence):
    if len(sequence) == 1:
        return sequence
    elif len(sequence) == 2:
        if sequence[0] < sequence[1]:
            return sequence
        else:
            sequence[0], sequence[1] = sequence[1], sequence[0]
            return sequence
    mid = len(sequence) // 2
    left = merge_sort(sequence[:mid])
    right = merge_sort(sequence[mid:])
    return merge(left, right)

def merge(sequence1, sequence2):
    index1, index2 = 0, 0
    sequence = []
    while index1 <= len(sequence1) - 1 and index2 <= len(sequence2) - 1:
        if sequence1[index1] < sequence2[index2]:
            sequence.append(sequence1[index1])
            index1 += 1
        else:
            sequence.append(sequence2[index2])
            index2 += 1
    if index1 == len(sequence1):
        sequence += sequence2[index2:]
    elif index2 == len(sequence2):
        sequence += sequence1[index1:]
    return sequence

  每层递归加起来相当于对于数组进行了一次扫描,共需进行 log ⁡ n \log{n} logn层递归,故时间复杂度为 n log ⁡ n n\log{n} nlogn;每层递归需使用一个数组存储数据,各层递归总数组长度为 n n n,故空间复杂度为 n n n
  最佳运行时间与最差运行时间均为 n log ⁡ n n\log{n} nlogn

求数组中的逆序对个数

def merge_sort(sequence, count = 0):
    if len(sequence) == 1:
        return sequence, 0
    mid = len(sequence) // 2
    left, left_count = merge_sort(sequence[:mid], count)
    right, right_count = merge_sort(sequence[mid:], left_count)
    return merge(left, right, left_count + right_count)

def merge(sequence1, sequence2, count):
    index1, index2 = 0, 0
    sequence = []
    while index1 <= len(sequence1) - 1 and index2 <= len(sequence2) - 1:
        if sequence1[index1] <= sequence2[index2]:
            sequence.append(sequence1[index1])
            index1 += 1
        else:
            sequence.append(sequence2[index2])
            count += len(sequence1) - index1
            index2 += 1
    if index1 == len(sequence1):
        sequence += sequence2[index2:]
    elif index2 == len(sequence2):
        sequence += sequence1[index1:]
    return sequence, count
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值