C语言快速排序

什么是快速排序?

快速排序(Quick Sort)是一种高效的排序算法,采用"分治"策略。它的核心思想是:选择一个基准值(pivot),将数组分成两部分,一部分比基准值小,另一部分比基准值大,然后递归地对这两部分进行排序。

为什么选择前后指针法?

在快速排序的几种实现方法中(Hoare版本、前后指针、挖坑法),前后指针法相对容易理解。

前后指针法思路

  1. 选择最左边的元素作为基准值(key)
  2. 定义两个指针:prev(慢指针)和cur(快指针)
  3. cur先移动,如果cur指向的元素小于key,prev就前进并交换prev和cur指向的元素
  4. 当cur走到数组末尾,将key与prev指向的元素交换
  5. 递归处理key左边和右边的子数组

C语言实现代码

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

// 交换两个元素的值
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 快速排序函数
void quickSort(int arr[], int left, int right) {
    // 递归终止条件:子数组长度小于等于1
    if (left >= right) {
        return;
    }
    
    // 选择最左边的元素作为基准值
    int key = arr[left];
    int prev = left;  // 慢指针
    int cur = left + 1;  // 快指针
    
    // cur移动,prev跟随
    while (cur <= right) {
        // 如果cur指向的元素小于基准值
        if (arr[cur] < key) {
            prev++;  // prev前进
            swap(&arr[cur], &arr[prev]);  // 交换cur和prev指向的元素
        }
        cur++;  // cur总是前进
    }
    
    // 将基准值放到正确位置
    swap(&arr[left], &arr[prev]);
    
    // 递归排序左右子数组
    quickSort(arr, left, prev - 1);
    quickSort(arr, prev + 1, right);
}

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

int main() {
    int arr[] = {10, 7, 8, 9, 1, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    printf("原始数组: ");
    printArray(arr, n);
    
    quickSort(arr, 0, n - 1);
    
    printf("排序后数组: ");
    printArray(arr, n);
    
    return 0;
}
  1. swap函数:用于交换两个元素的值,是排序中常用的操作。

  2. quickSort函数

    • leftright表示当前要排序的子数组的左右边界
    • 选择最左边的元素作为基准值key
    • prev从基准值后一个位置开始,curprev的下一个位置开始
    • cur向前移动,如果遇到比key小的元素,prev就前进并交换prevcur指向的元素
    • cur走到数组末尾,将keyprev指向的元素交换
  3. 递归 :将数组分成两部分,分别对左右子数组递归调用quickSort

快速排序的执行过程(以10, 7, 8, 9, 1, 5为例)

  1. 选择10作为基准值
  2. 从左到右遍历:7、8、9都比10小,1和5也比10小
  3. 遍历完成后,10应该放在第5个位置(索引4)
  4. 交换10和1,得到1, 7, 8, 9, 10, 5
  5. 递归排序1, 7, 8, 95

时间复杂度

最佳情况:O(n log n) - 每次都能将数组分成两个相等的子数组

最坏情况:O(n²) - 数组已经基本有序,每次只能减少一个元素

平均情况:O(n log n)。

1.递归的终止条件if (left >= right)很重要,避免无限递归。

2.注意cur的边界条件,要小于等于right

3.基准值的选择影响排序效率,这里选择最左边的元素是简化实现

相关推荐
2501_9065651215 分钟前
数学之美探究
算法
oier_Asad.Chen25 分钟前
【洛谷题解/AcWing题解/OI学习笔记】洛谷P2868【USACO07DEC】Sightseeing Cows G(01分数规划求最大比率)
算法·图论·spfa·二分·负环
leisoo80972 小时前
财报数据怎么排雷本地化Python构建财务异常预警系统
人工智能·python·算法
luj_17684 小时前
塔防牌:策略与卡牌的智慧碰撞
服务器·c语言·开发语言·经验分享·算法
wuyk5555 小时前
3.链表:用指针串联的动态数据结构
c语言·开发语言·数据结构·链表
郝学胜-神的一滴5 小时前
干货版《算法导论》17:二叉树核心原理、遍历逻辑与高阶实操全解
数据结构·c++·python·算法·计算机·编程
爱编程的小新☆5 小时前
【LeetCode】从递归到 Flood Fill:5 道题吃透 DFS 的选择、回溯与标记
java·算法·leetcode·深度优先·回溯·flood fill
Water_Sunzhipeng5 小时前
2024牛客暑期多校训练营1
算法
hetao17338375 小时前
2026-08-09~08-14 hetao1733837 的刷题记录
c++·算法
技术小黑5 小时前
RNN算法实战系列06 | LSTM 实现糖尿病探索与预测
rnn·算法·lstm