【leetcode】排序算法

本文深入讲解了十种经典的排序算法,包括插入排序、选择排序、交换排序、归并排序和基数排序等,详细介绍了每种算法的实现原理、代码实现及性能分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法分类

在这里插入图片描述

算法实现

1. 插入排序

1.1 直接插入排序

每次将 第 i 位 的数值插入到 前面最合适的位置。

def insert_sort(x):
    if not x or len(x) <= 1:
        return x
    for i in range(1, len(x)):
        for j in range(i):
            if x[j] > x[i]:
                tmp = x[i]
                for p in range(i, j, -1):
                    x[p] = x[p-1]
                x[j] = tmp
    return x
1.2 希尔排序

将数组拆分成多个子数组,分别进行直接插入排序。

实现过程略。

2. 选择排序

2.1 简单选择排序

每次选择 第 i ~ len(x)-1 位 中最小的值,放在 第 i 位 。

def select_sort(x):
    if not x or len(x) <= 1:
        return x
    for i in range(len(x)-1):
        for j in range(i+1, len(x)):
            if x[i] > x[j]:
                x[i], x[j] = x[j], x[i]
    return x
2.2 堆排序

略。

法一:

def build_max_heap(x):
    import math
    for i in range(math.floor(len(x)/2),-1,-1):
        heapify(x,i)

def heapify(x, i):
    left = 2*i+1
    right = 2*i+2
    largest = i
    if left < arrLen and x[left] > x[largest]:
        largest = left
    if right < arrLen and x[right] > x[largest]:
        largest = right

    if largest != i:
        swap(x, i, largest)
        heapify(x, largest)

def swap(x, i, j):
    x[i], x[j] = x[j], x[i]

def heap_sort(x):
    global arrLen
    arrLen = len(x)
    build_max_heap(x)
    for i in range(len(x)-1,0,-1):
        swap(x,0,i)
        arrLen -=1
        heapify(x, 0)
    return x

法二:

def one_heap_sort(x, l, r):
    if r-l <= 0:
        return
    if r-l == 1 and x[l] > x[r]:
        x[l], x[r] = x[r], x[l]
    else:
        middle = l + (r-l-1) // 2
        one_heap_sort(x, l, middle)
        one_heap_sort(x, middle+1, r-1)
        if x[middle] > x[r]:
            x[middle], x[r] = x[r], x[middle]
        if x[r-1] > x[r]:
            x[r-1], x[r] = x[r], x[r-1]

# 依次将最大值放到数组的后面
def heap_sort(x):
    for i in range(len(x)-1, 0, -1):
    # for i in range(len(x)):
        one_heap_sort(x, 0, i)

测试用例:

x = [1, 10, 8, 200, 50, 4]
heap_sort(x)
assert x == [1, 4, 8, 10, 50, 200]

3. 交换排序

3.1 冒泡排序

每次通过相邻位的值交换,将 第 0 ~ len(x)-i-1 位 中最大的值,放在 第 len(x)-i-1 位 。

def bubble_sort(x):
    if not x or len(x) <= 1:
        return x
    for i in range(len(x)):
        for j in range(1, len(x)-i):
            if x[j-1] > x[j]:
                x[j-1], x[j] = x[j], x[j-1]
    return x
3.2 快速排序

法一:

def quick_sort(x):
    if not x or len(x) <= 1:
        return x
    base = x[0]
    left = [ele for ele in x[1:] if ele <= base]
    right = [ele for ele in x[1:] if ele > base]
    return quick_sort(left) + [base] + quick_sort(right)

法二:

def quick_sort(x, low, high):
    if not x or len(x) <= 1 or low >= high:
        return x
    base, l, r = x[low], low, high
    while l < r:
        while l < r and x[r] >= base:
            r -= 1
        x[l] = x[r]
        while l < r and x[l] <= base:
            l += 1
        x[r] = x[l]
    x[l] = base
    quick_sort(x, low, l-1)
    quick_sort(x, l+1, high)
    return x

法三:

def quick_sort(x, low, high):
    if not x or len(x) <= 1 or low >= high:
        return x
    queue = [low, high]
    while queue:
        l, r = queue.pop(0), queue.pop(0)
        if l >= r:
            continue
        i = l - 1
        for j in range(l, r):
            if x[j] <= x[r]:
                i += 1
                x[i], x[j] = x[j], x[i]
        x[i+1], x[r] = x[r], x[i+1]
        queue.extend([l, i, i+2, r])
    return x

测试用例:

lst_a = list(range(40))
import random
random.shuffle(lst_a)
print(lst_a)
quick_sort(lst_a, 0, 39)
print(lst_a)

4. 归并排序

def merge(left, right):
    res, i, j = [], 0, 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            res.append(left[i])
            i += 1
        else:
            res.append(right[j])
            j += 1
    res += left[i:] or right[j:]
def merge_sort(x):
    if not x or len(x) <= 1:
        return x
    mid = len(x) // 2
    left = merge_sort(x[:mid])
    right = merge_sort(x[mid:])
    return merge(left, right)

5. 基数排序

略。

算法性能

Note:这里的 log底数为2在这里插入图片描述

  • 平均时间复杂度:一般为n2,只有 堆排、快排和归排 是nlogn。
  • 空间复杂度:一般为1,只有 堆排 是nlogn,归排 是 n。
  • 稳定性:一般都是不稳定的,只有 直接插排、冒泡排、归排和基排 是稳定的。

计算复杂度:对数计算器


[1] 十大经典排序算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值