嵌入式 - 数据结构与算法:(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 

相关推荐
隔窗听雨眠20 小时前
15分钟解LeetCode
算法·leetcode·面试
P-ShineBeam20 小时前
智能体-DeepAgent入门
人工智能·python·算法·语言模型·自然语言处理
菜菜的顾清寒20 小时前
力扣HOT10(29) 删除链表的倒数第 N 个结点
算法·leetcode·链表
拂拉氏1 天前
【项目分享-知识讲解】C++标准库string类的模拟实现+KMP算法讲解+哈希思想了解
开发语言·c++·算法·kmp算法·哈希·string类
Black蜡笔小新1 天前
自动化AI算法训练服务器DLTM助力医学影像分析进入AI智能分析新时代
人工智能·算法·自动化
手写码匠1 天前
深入解析大模型架构之争:全能通用模型 vs 领域专精模型
人工智能·深度学习·算法·aigc
浅念-1 天前
LeetCode 回溯算法题——综合练习
数据结构·c++·算法·leetcode·职场和发展·深度优先·dfs
列星随旋1 天前
线段树和树状数组的学习
学习·算法