常用排序算法(python)

1 冒泡排序

时间复杂度:O(n2),空间复杂度 O(1)
稳定性: 稳定

def bubble_sort(nums):
    for i in range(len(nums)-1):
        flag = False
        for j in range(0, len(nums)-i-1):
            if nums[j] > nums[j+1]:
                swap(nums, j, j+1)
                flag = True
        if not flag:
            break
    return nums

在这里插入图片描述
注: swap函数

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

2 快速排序

时间复杂度:O(nlogn),空间复杂度 O(1)
时间复杂度: 每一轮需要比较n次, 需要比较logn轮
稳定性: 不稳定(相同的元素排序后可能会换位)

def partition(nums, left, right):
    """分割, 单边循环法, 把小于基准的放基准前面"""
    pivot = left

    i = j = pivot + 1  # i代表小于基准的位置, j代表当前遍历到的位置
    while j <= right:  # 没遍历完
        if nums[j] < nums[pivot]:  # 右边 比 基准小, 就交换
            swap(nums, i, j)
            i += 1
        j += 1
    swap(nums, pivot, i-1)
    return i-1

def quick_sort(nums, left, right):
    if left < right:
        pivot = partition(nums, left, right)
        quick_sort(nums, left, pivot-1)
        quick_sort(nums, pivot+1, right)

在这里插入图片描述

3 选择排序

时间复杂度:O(n2), 空间复杂度 O(1)
稳定性: 不稳定

def select_sort(nums):
    for i in range(len(nums)):  # i记录当前的轮数
        min_idx = i
        for j in range(i+1, len(nums)):
            if nums[j] < nums[min_idx]:
                min_idx = j
        swap(nums, i, min_idx)  # 一轮结束后把最小的移到最前

在这里插入图片描述

4 堆排序

时间复杂度:O(nlogn), 空间复杂度 O(1)
时间复杂度: 每一轮需要比较logn次, 需要比较n轮
稳定性: 不稳定

def heapify(nums, i, size):
    """调整大顶堆"""
    left, right = 2*i+1, 2*i+2  # 第i号结点的左子树和右子树
    largest = i
    if left < size and nums[left] > nums[largest]:
        largest = left
    if right < size and nums[right] > nums[largest]:
        largest = right
    if largest != i:  # 若发现左右子树比父结点大, 则互换位置, 再继续向下调整堆
        swap(nums, i, largest)
        heapify(nums, largest, size)

def heap_sort(nums):
	size = len(nums)
	for i in range(size//2, -1, -1):  # 构建大顶堆
    	heapify(nums, i, size)
    for i in range(len(nums)-1, 0, -1):  # 从最后一个结点(闭)遍历到倒数第一个结点(开)
        swap(nums, 0, i)  # 把最大的元素和最后的元素交换位置
        size -= 1  # size-1, 最后的元素就是最大的, 不用再调整
        heapify(nums, 0, size)  # 把前面的元素继续调整为大顶堆

5 插入排序

时间复杂度:O(n2),空间复杂度 O(1)
稳定性: 稳定

def insert_sort(nums):
    for i in range(1, len(nums)):
        cur = nums[i]  # 第i个数
        pre_idx = i - 1
        while pre_idx >=0 and nums[pre_idx] > cur:  # 若之前的数大于第i个数, 往后挪
            nums[pre_idx + 1] = nums[pre_idx]
            pre_idx -= 1  # 跟前面的每一个数比较
        nums[pre_idx + 1] = cur

在这里插入图片描述

6 希尔排序

时间复杂度:O(n2),空间复杂度 O(1)
稳定性: 不稳定

def shell_sort(nums):
    n = len(nums)
    gap = n // 2
    while gap >= 1:
        for i in range(gap):  # i为每一个子序列起始元素的索引
            j = i
            while j+gap < n:
                if nums[j+gap] < nums[j]:  # 每一个子序列内排序
                    swap(nums, j, j+gap)
                j += gap
        gap //= 2

7 归并排序

时间复杂度:O(nlogn),空间复杂度 O(n)
稳定性: 不稳定

def merge(left, right):
    """排序, 合并"""
    ret = []
    while left and right:
        if left[0] <= right[0]:
            ret.append(left.pop(0))
        else:
            ret.append(right.pop(0))
    ret.extend(left or right)
    return ret


def merge_sort(nums):
    """对半分"""
    if len(nums) < 2:
        return nums
    mid = len(nums) // 2
    left, right = nums[:mid], nums[mid:]
    return merge(merge_sort(left), merge_sort(right))

在这里插入图片描述

参考资料

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值