排序算法(6):快速排序

问题

排序 [30, 24, 5, 58, 18, 36, 12, 42, 39]

快速排序

快速排序采用分治策略,首先从数组中选择一个元素作为基准元素。以基准元素为标准,将问题分解为两个子序列,使小于等于基准元素的子序列在左侧,大于基准元素的子序列在右侧。然后将两个子序列分别进行快速排序,将排序好的两个子序列合并在一起,完成排序。

图解

快速排序算法的重点是选择基准元素,并将其移动到正确的位置。

  1. 初始化第一个元素为基准元素,pivot = 30,i = low,j = high
  2. 从数组的右边位置向左找,一直找到小于 pivot 的元素 12,与基准元素交换位置,i += 1
  3. 从数组的左边位置向右找,一直找到大于 pivot 的元素 58,与基准元素交换位置,j -= 1
  4. 从数组的右边位置向左找,一直找到小于 pivot 的元素 18,交换位置,i += 1。此时 i = j,第一轮排序结束,返回 i 的位置,mid = i
  1. 完成第一轮排序之后,以 mid 为界,将原数据分为两个子序列,左侧子序列都比 pivot 小,右侧子序列都比 pivot 大,然后分别对两个子序列进行快速排序。

代码

py 复制代码
# 获取基准元素的正确位置
def partition(nums, low, high):
    pivot = nums[low]
    i, j = low, high

    while i < j:
        while i < j and nums[j] >= pivot:   # 从右向左找小于pivot的数,并交换位置
            j -= 1
        if i < j: 
        	nums[i], nums[j] = nums[j], nums[i]
        	i += 1
        while i < j and nums[i] <= pivot:   # 从左向右找大于pivot的数,并交换位置
            i += 1
        if i < j: 
        	nums[i], nums[j] = nums[j], nums[i]
        	j -= 1

    return i

def quick_sort(nums, low=0, high= len(nums)-1):
    if low < high:
        mid = partition(nums, low, high)
        quick_sort(nums, low, mid-1)
        quick_sort(nums, mid+1, high)

    return nums

时间复杂度

  • 快速排序最好的时间复杂度是 O(nlogn)

    最理想的情况下,每次划分将问题分解为两个规模都是 n/2 的子问题,递归求解

    递归最终规模为 1,令 2x = n,x = logn,那么

  • 快速排序最块的时间复杂度为 O(n2)

    在最坏的情况下,每次划分将问题分解后,基准元素的左侧或右侧没有元素,基准元素的另一侧为 1 个规模为 n-1 的子问题,递归求解

算法优化

在上述算法中,每次交换都是在和基准元素交换,但实际没必要这样做。只需要从右往左找到小于等于基准元素的数,再从左往右找到大于基准元素的数,将这两个数交换,一直交替进行,直到 i 和 j 碰头,这时将其和基准元素交换,这样就完成了一次划分过程。

  1. 首先取数组第一个元素为基准元素 pivot = 30

  2. 从数组的右边往左找,一直找到小于 pivot 的元素 12,从数组的左边往右找,一直找到大于 pivot 的元素 58,然后将它们交换位置

  3. 继续从数组的右边往左找,找到小于 pivot 的元素 18,从左往右找大于 pivot 直到 i = j 时停止

  4. 将基准元素和 i 位置的元素交换,返回 i 的位置 mid = i,第一轮排序结束

代码

py 复制代码
def partition(nums, low, high):
    pivot = nums[low]
    i, j = low, high

    while i < j:
        while i < j and nums[j] > pivot:
            j -= 1

        while i < j and nums[i] <= pivot:
            i += 1

        if i < j:
            nums[i], nums[j] = nums[j], nums[i]
            i += 1
            j -= 1

	if nums[i] > pivot:
		nums[i-1], nums[low] = nums[low], nums[i-1]
		return i-1

    nums[low], nums[i] = nums[i], nums[low]

    return i
相关推荐
计算机安禾2 小时前
【计算机网络】第10篇:距离矢量路由算法——Bellman-Ford方程与RIP协议的特性分析
计算机网络·算法
机器学习之心2 小时前
基于开普勒优化算法(KOA)优化CNN-BiGRU-Attention混合网络的时间序列预测模型,MATLAB代码
算法·时间序列预测模型·开普勒优化算法
Java成神之路-3 小时前
【LeetCode 刷题笔记】367.有效的完全平方数 | 二分查找经典刷题题解
算法·leetcode
一切皆是因缘际会11 小时前
从概率拟合到内生心智:2026 下一代 AI 架构演进与落地实践
人工智能·深度学习·算法·架构
Java成神之路-11 小时前
【LeetCode 刷题笔记】34. 在排序数组中查找元素的第一个和最后一个位置 | 二分查找经典刷题题解
算法·leetcode
不忘不弃11 小时前
用BFS方法求解平分汽油问题
算法·宽度优先
AI科技星11 小时前
全域数学·72分册·射影原本 无穷维射影几何卷细化子目录【乖乖数学】
人工智能·线性代数·算法·机器学习·数学建模·数据挖掘·量子计算
风落无尘11 小时前
《智能重生:从垃圾堆到AI工程师》——第四章 变化的艺术
人工智能·线性代数·算法
JAVA面经实录91711 小时前
计算机基础(完整版·超详细可背诵)
java·linux·数据结构·算法
AC赳赳老秦11 小时前
知识产权辅助:用 OpenClaw 批量生成专利交底书 / 软著申请材料,自动校验格式与内容合规性
java·人工智能·python·算法·elasticsearch·deepseek·openclaw