嵌入式 - 数据结构与算法:(1-12)排序算法 - 快速排序(Quick Sort)

上一篇 下一篇

目 录


3)快速排序(Quick Sort)

快速排序是一种高效的分治排序算法,由 Tony Hoare 于 1960 年提出。

参考视频:数据结构合集 - 快速排序(算法过程, 效率分析, 稳定性分析)_哔哩哔哩_bilibili

3.1)核心思想

核心思想是:选一个"基准值"(pivot),将数组划分为两部分:

  • 左边:所有元素 ≤ 基准值
  • 右边:所有元素 ≥ 基准值
  • 然后 递归地对左右两部分分别排序。

整个过程采用 "分而治之" 策略。

3.2)算法步骤(升序)

  1. 选择基准值(pivot):通常选首元素、尾元素或中间元素;
  2. 分区:
    • 重新排列数组,使得比 pivot 小的在左边,大的在右边;
    • 最终 pivot 被放到其最终正确位置;
  3. 递归处理:
    • 对 pivot 左侧子数组递归快排;
    • 对 pivot 右侧子数组递归快排;
  4. 递归终止条件:子数组长度 ≤ 1(自然有序)。

简单说就是: 先选个基准值(首元素/尾元素/中间元素等),然后小于它的放左边(左分区),大于它的放右边(右分区),此时这个基准值就处于正确位置了;然后左分区和右分区分别再各自选个基准值,再分区......递归循环;最后当没有分区可分了,那么就是有序了。

3.3)时间与空间复杂度

情况 时间复杂度
最好/平均 O(n log n)
最坏 O(n²) ------ 如每次选到最大/最小值作 pivot(如已排序数组)
  • 空间复杂度:O(log n)(递归调用栈深度,平均情况);最坏 O(n)
  • 稳定性:❌ 不稳定(分区过程中可能改变相等元素的相对顺序)
  • 原地排序:是(仅使用少量额外空间)

实际工程中常通过 随机化 pivot 或 三数取中法 避免最坏情况。

3.4)C 语言代码示例

分区方法有很多,这里采用经典的 左右指针法(Hoare 分区),效率较高(看参考视频就明白了)。

c 复制代码
#include <stdio.h>

/**
 * @brief:		partition ------ 分区函数:返回 pivot 的最终位置
 * @note:		low - 当前要处理的子数组的起始下标; high - 当前要处理的子数组的结束下标	
 */
int partition(int arr[], int low, int high) {
    int pivot = arr[low]; // 选择第一个元素作为 pivot
    int left = low;
    int right = high;

    while (left < right) {
        // 从右往左找第一个 <= pivot 的元素
        while (left < right && arr[right] >= pivot)
            right--;
        // 从左往右找第一个 >= pivot 的元素
        while (left < right && arr[left] <= pivot)
            left++;
        // 交换两个错位的元素
        if (left < right) {
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
        }
    }
    // 将 pivot 放到正确位置(与 left/right 重合处交换)
    arr[low] = arr[left];
    arr[left] = pivot;

    return left; // 返回 pivot 的索引
}

// 快速排序主函数
void quick_sort(int arr[], int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high); // 获取分区点
        quick_sort(arr, low, pi - 1);      // 递归排序左半部分
        quick_sort(arr, pi + 1, high);     // 递归排序右半部分
    }
}

// 打印数组
void print_array(int arr[], int n) {
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

// 主函数:测试快速排序
int main() {
    int arr[] = {64, 34, 25, 12, 22, 11, 90};
    int n = sizeof(arr) / sizeof(arr[0]);

    printf("原始数组: ");
    print_array(arr, n);

    quick_sort(arr, 0, n - 1);

    printf("排序后数组: ");
    print_array(arr, n);

    return 0;
}

运行结果如下:

复制代码
原始数组: 64 34 25 12 22 11 90 
排序后数组: 11 12 22 25 34 64 90 

相关推荐
Coder-magician23 分钟前
图论总结篇
算法·图论
有同事要进步29 分钟前
Leecode第68题:x的平方根
java·数据结构·算法
吹什么轩35 分钟前
linux系统复习:进程优先级与O(1)调度
java·linux·算法
开开心心就好1 小时前
安卓PDF处理工具,免费无广告零弹窗
android·服务器·开发语言·算法·pdf·ocr
zyl76517 小时前
FlashAttention 详解:从 GPU 硬件、普通 Attention 到分块计算与 Online Softmax
算法
爱读书的小胖20 小时前
LeetCode 122:买卖股票的最佳时机 II(C)解题分析
算法
结局无敌20 小时前
React Native for OpenHarmony 实战:三方库 react-native-modal-dialog 的鸿蒙化适配指南
深度学习·算法·react native·react.js·harmonyos
OPEN-F21 小时前
ROS2系列教程:上位机建图与导航(原理综合)
算法·机器人
weixin_3077791321 小时前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
tomwang032221 小时前
路径优化建模、优化算法分类及工程化小结
算法·数学建模·分类