跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C算法

C 语言快速排序算法详解与优化实现

C 语言快速排序通过选取基准值将数组划分为小于和大于基准的两部分,递归处理子区间。基础 Hoare 版本,并引入三数取中法避免最坏情况,结合小区间优化策略提升性能。此外涵盖非递归实现方案,利用栈结构替代系统递归调用,防止栈溢出。内容包含完整代码逻辑与关键步骤解析,适合深入理解排序算法原理及工程实践。

imJackJia发布于 2026/3/24更新于 2026/5/23 浏览
C 语言快速排序算法详解与优化实现

C 语言快速排序算法详解与优化实现

快速排序是 C 语言标准库中常用的排序算法之一,以其平均时间复杂度 O(N log N) 和原地排序特性被广泛使用。本文将深入剖析其原理,从基础 Hoare 分区法到三数取中、小区间优化及非递归实现,提供完整的工程实践代码。

一、快速排序基础(Hoare 分区)

1. 核心思想

快速排序的核心在于选取一个基准值(Key),通过交换操作将数组划分为两部分:左侧所有元素小于 Key,右侧所有元素大于 Key。随后对左右两个子区间递归执行相同操作,直到区间长度为 1。

2. 实现思路

采用双指针法(L 和 R):

  • 右指针 R 向左移动,寻找比 Key 小的值;
  • 左指针 L 向右移动,寻找比 Key 大的值;
  • 相遇时停止,交换 Key 与相遇点元素,完成一次分区。

3. 代码实现

void QuickSort1(int* a, int left, int right)
{
    if (left >= right)
        return;

    int key = left;
    int L = left;
    int R = right;

    while (left < right)
    {
        while (left < right && a[right] >= a[key])
            right--;
        while (left < right && a[left] <= a[key])
            left++;
        Swap(&a[left], &a[right]);
    }
    Swap(&a[right], &a[key]);
    key = right;

    QuickSort1(a, L, key - 1);
    QuickSort1(a, key + 1, R);
}

二、快速排序进阶(三数取中)

1. 存在的问题

若固定选择第一个元素为 Key,当数组已有序或接近有序时,分区极不均匀,导致时间复杂度退化为 O(N^2)。

2. 优化方案:三数取中

选取数组首、尾、中间三个位置的值,取其中位数作为 Key。这能有效避免极端情况下的性能下降。

3. 代码实现

int FindKey(int* a, int left, int right)
{
    int mid = (left + right) / 2;
    if (a[left] > a[right])
    {
        if (a[right] > a[mid])
            return right;
          (a[mid] > a[left])
             left;
        
             mid;
    }
    
    {
         (a[left] > a[mid])
             left;
          (a[mid] > a[right])
             right;
        
             mid;
    }
}

 
{
     (left >= right)
        ;

     L = left;
     R = right;
     key = FindKey(a, left, right);
    Swap(&a[key], &a[left]);
    key = left;

     (left < right)
    {
         (left < right && a[right] >= a[key])
            right--;
         (left < right && a[left] <= a[key])
            left++;
        Swap(&a[left], &a[right]);
    }
    Swap(&a[right], &a[key]);
    key = right;

    QuickSort1(a, L, key - );
    QuickSort1(a, key + , R);
}
else
if
return
else
return
else
if
return
else
if
return
else
return
void
QuickSort1
(int* a, int left, int right)
if
return
int
int
int
while
while
while
1
1

三、快速排序高阶(小区间优化)

1. 优化思路

递归深度过深会消耗大量栈空间。当区间长度较小时(如小于 10),递归开销可能超过直接排序的开销。此时可切换至插入排序或堆排序处理小区间,减少递归调用次数。

2. 辅助函数

三数取中
int FindKey(int* a, int left, int right)
{
    int mid = (left + right) / 2;
    if (a[left] > a[right])
    {
        if (a[right] > a[mid])
            return right;
        else if (a[mid] > a[left])
            return left;
        else
            return mid;
    }
    else
    {
        if (a[left] > a[mid])
            return left;
        else if (a[mid] > a[right])
            return right;
        else
            return mid;
    }
}
分区函数
int PartSort1(int* a, int left, int right)
{
    int key = FindKey(a, left, right);
    Swap(&a[key], &a[left]);
    key = left;
    while (left < right)
    {
        while (left < right && a[right] >= a[key])
            right--;
        while (left < right && a[left] <= a[key])
            left++;
        Swap(&a[left], &a[right]);
    }
    Swap(&a[right], &a[key]);
    return right;
}
堆排序(用于小区间)
void InsertSort(int* a, int n)
{
    for (int i = 0; i < n - 1; i++)
    {
        int end = i;
        int tmp = a[end + 1];
        while (end >= 0)
        {
            if (tmp < a[end])
                a[end + 1] = a[end];
            else
                break;
            --end;
        }
        a[end + 1] = tmp;
    }
}

void AdJustDown(int* a, int parent, int size)
{
    int child = 2 * parent + 1;
    while (child <= size - 1)
    {
        if (child + 1 <= size - 1 && a[child + 1] > a[child])
            child++;
        if (a[child] > a[parent])
        {
            Swap(&a[child], &a[parent]);
            parent = child;
            child = 2 * parent + 1;
        }
        else
            break;
    }
}

void HeapSort(int* a, int sz)
{
    int i;
    for (i = (sz - 1 - 1) / 2; i >= 0; i--)
        AdJustDown(a, i, sz);
    for (i = sz - 1; i > 0; i--)
    {
        Swap(&a[0], &a[i]);
        AdJustDown(a, 0, i);
    }
}
主框架
void QuickSort1(int* a, int left, int right)
{
    if (left >= right)
        return;

    int g = right - left + 1;
    if (g < 10)
        HeapSort(a + left, g);
    else
    {
        int key = PartSort1(a, left, right);
        QuickSort1(a, left, key - 1);
        QuickSort1(a, key + 1, right);
    }
}

四、快速排序非递归实现

1. 问题背景

递归实现依赖系统栈,数据量过大可能导致栈溢出。使用显式栈结构模拟递归过程可解决此问题。

2. 实现思路

利用栈存储待处理的区间范围 [Left, Right]。每次弹出一个区间进行分区,若子区间有效则压入栈中,直至栈空。

3. 代码实现

栈定义
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

typedef int STDataType;

typedef struct Stack
{
    STDataType* a;
    int size;
    int capacity;
} Stack;

void StackInit(Stack* ps);
void StackPush(Stack* ps, STDataType data);
void StackPop(Stack* ps);
STDataType StackTop(Stack* ps);
int StackSize(Stack* ps);
int StackEmpty(Stack* ps);
void StackDestroy(Stack* ps);
栈实现
#include"Stack.h"

void StackInit(Stack* ps)
{
    assert(ps);
    ps->a = NULL;
    ps->capacity = 0;
    ps->size = 0;
}

void StackPush(Stack* ps, STDataType data)
{
    assert(ps);
    if (ps->size == ps->capacity)
    {
        int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
        STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
        if (tmp == NULL)
        {
            perror("realloc");
            return;
        }
        ps->a = tmp;
        ps->capacity = newcapacity;
    }
    ps->a[ps->size] = data;
    ps->size++;
}

void StackPop(Stack* ps)
{
    assert(ps && ps->size > 0);
    ps->size--;
}

STDataType StackTop(Stack* ps)
{
    assert(ps && ps->size > 0);
    return ps->a[ps->size - 1];
}

int StackSize(Stack* ps)
{
    assert(ps);
    return ps->size;
}

int StackEmpty(Stack* ps)
{
    assert(ps);
    return ps->size == 0;
}

void StackDestroy(Stack* ps)
{
    assert(ps);
    free(ps->a);
    ps->a = NULL;
    ps->capacity = 0;
    ps->size = 0;
}
快速排序主体
void QuickSortNonR(int* a, int left, int right)
{
    Stack S;
    StackInit(&S);
    StackPush(&S, right);
    StackPush(&S, left);

    while (!StackEmpty(&S))
    {
        int L = StackTop(&S);
        StackPop(&S);
        int R = StackTop(&S);
        StackPop(&S);

        if (L >= R)
            continue;

        int g = R - L + 1;
        if (g < 10)
            HeapSort(a + L, g);
        else
        {
            int key = PartSort1(a, L, R);
            if (R - key - 1 > 1)
            {
                StackPush(&S, R);
                StackPush(&S, key + 1);
            }
            if (key - 1 - L > 1)
            {
                StackPush(&S, key - 1);
                StackPush(&S, L);
            }
        }
    }
    StackDestroy(&S);
}

本文涵盖了快速排序从理论到工程优化的完整路径。理解这些变式有助于在实际开发中根据数据特征选择最优策略。

目录

  1. C 语言快速排序算法详解与优化实现
  2. 一、快速排序基础(Hoare 分区)
  3. 1. 核心思想
  4. 2. 实现思路
  5. 3. 代码实现
  6. 二、快速排序进阶(三数取中)
  7. 1. 存在的问题
  8. 2. 优化方案:三数取中
  9. 3. 代码实现
  10. 三、快速排序高阶(小区间优化)
  11. 1. 优化思路
  12. 2. 辅助函数
  13. 三数取中
  14. 分区函数
  15. 堆排序(用于小区间)
  16. 主框架
  17. 四、快速排序非递归实现
  18. 1. 问题背景
  19. 2. 实现思路
  20. 3. 代码实现
  21. 栈定义
  22. 栈实现
  23. 快速排序主体
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Trae AI 原生 IDE 安装与使用指南
  • OpenCLaw Web UI 无法访问 Not Found 问题排查与解决
  • Claude Code 模型参数配置与实战指南
  • Stable Diffusion WebUI 模型管理:Checkpoint、VAE 及 LoRA 配置实战
  • Go Web 开发核心理论指南
  • AAAI2025 PC-BEV:多坐标系融合策略实现点云分割加速与精度提升
  • 基于内网穿透实现本地 WebSocket 服务公网访问
  • 使用 ChatGPT 降低毕业论文 AIGC 检测率的策略
  • LangChain Agent 智能应用构建指南
  • Visual C++ 运行库修复指南:解决 Windows 程序无法启动问题
  • FPGA 开发环境搭建:Vivado 与 Vitis 2023.1 安装指南
  • Python+Agent 入门实战:搭建可复用 AI 智能体
  • OpenClaw 推动低代码 AI 向执行层演进:从工具赋能到生态重构
  • Java 反射、枚举与 Lambda 表达式
  • VSCode GitHub Copilot 插件无法加载模型解决方案
  • OpenClaw 部署实战:接入 Minimax/DeepSeek 及飞书机器人
  • AI 编程助手价格与体验对比:Claude Code vs 国产替代
  • AI 辅助小说创作:三步心法与十款工具实测
  • QGIS:Maxar Open Data全球高分辨率遥感影像(0.3-0.5米)14TB免费获取
  • ToDesk ToClaw 深度测评:OpenClaw 的云端自动化落地实践

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online