C语言之快速排序

目录

[一 简介](#一 简介)

[二 代码实现](#二 代码实现)

快速排序基本原理:

C语言实现快速排序的核心函数:

[三 时空复杂度](#三 时空复杂度)

A.时间复杂度

B.空间复杂度

C.总结:


一 简介

快速排序是一种高效的、基于分治策略的比较排序算法,由英国计算机科学家C.A.R. Hoare在1960年提出。

二 代码实现

以下是使用C语言实现快速排序的基本步骤和代码示例:

快速排序基本原理:

  • 选择一个基准元素(pivot),通常选择数组的第一个元素或者最后一个元素。
  • 将所有比基准小的元素移动到基准元素之前,所有比基准大的元素移动到基准之后。这个操作被称为分区操作(partition)。
  • 对基准左右两边的子数组分别递归地进行上述操作。

C语言实现快速排序的核心函数:

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

// 分区操作,返回基准元素最后的位置
int partition(int arr[], int low, int high) {
    int pivot = arr[high]; // 基准元素(这里选取了数组的最后一个元素)
    int i = (low - 1);  // 指针i初始化为low - 1

    for (int j = low; j <= high - 1; j++) {
        // 如果当前元素小于或等于基准元素,则与指针i所指向位置的元素交换,并将i后移一位
        if (arr[j] <= pivot) {
            i++;
            // 交换arr[i]和arr[j]
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }

    // 把基准元素放到正确的位置(即所有小于它的元素都在它前面)
    int temp = arr[i + 1];
    arr[i + 1] = arr[high];
    arr[high] = temp;

    return (i + 1);
}

// 快速排序主函数
void quickSort(int arr[], int low, int high) {
    if (low < high) {
        // pi是基准元素最后所在的位置
        int pi = partition(arr, low, high);

        // 对基准元素左侧子数组进行递归排序
        quickSort(arr, low, pi - 1);

        // 对基准元素右侧子数组进行递归排序
        quickSort(arr, pi + 1, high);
    }
}

// 测试快速排序
int main() {
    int arr[] = {10, 7, 8, 9, 1, 5};
    int n = sizeof(arr)/sizeof(arr[0]);
    quickSort(arr, 0, n-1);
    
    printf("Sorted array: \n");
    for (int i=0; i<n; i++)
        printf("%d ", arr[i]);
    return 0;
}

这段代码首先定义了一个partition函数,该函数负责对输入数组进行一次划分操作,然后通过quickSort函数递归地对左右两个子数组执行同样的操作,直到子数组只剩下一个元素为止(因为只有一个元素的数组被认为是有序的)。最终,整个数组会被排序完成。

三 时空复杂度

A.时间复杂度

  • 平均情况 :当每次划分都能将数组大致均分为两个子数组时,快速排序的平均时间复杂度为 。这是由于每次递归调用都会将问题规模减半,并且需要对 n 个元素进行 层递归。

  • 最好情况 :最好的情况即每次选取的基准都能将数组完美地划分为大小相等的两部分,此时时间复杂度也是 。

  • 最坏情况 :最坏的情况是每次划分后,一个子数组为空或只有一个元素,而另一个子数组包含所有剩余元素。例如,对于已经完全有序的数组,这种情况会导致退化为的时间复杂度。然而,在实际应用中,可以通过随机化选择基准元素(如三数取中法)来避免这种极端情况的发生,从而保证快速排序在期望下的时间复杂度仍为。

B.空间复杂度

  • 递归栈空间 :快速排序是一种递归算法,其递归深度取决于输入数据的结构。在最坏情况下,递归深度可以达到 n,所以空间复杂度为 O(n)。但大多数情况下,递归深度为,此时的空间复杂度主要来自于递归调用栈,约为 。

  • 辅助空间:快速排序在原地排序的情况下不需要额外的数据存储空间,除了递归调用栈所占用的空间外,算法本身不使用其他额外空间,因此辅助空间复杂度可认为是 O(1)。

C.总结:

综上所述,快速排序在理想情况下是一个非常高效的排序算法,具有较好的平均性能。不过需要注意的是,为了避免最坏情况下的性能下降,通常会采取一些策略优化基准元素的选择方法。

相关推荐
进击的大海贼8 小时前
基于C#开发的久坐提醒工具
开发语言·c#
夏幻灵8 小时前
每日一题:LeetCode 1:两数之和——从暴力枚举到 Map 哈希表优化
算法·leetcode·散列表
平生幻8 小时前
unbuntu虚拟机确认python安装位置
开发语言·python
段一凡-华北理工大学9 小时前
高炉炼铁机器视觉与智能识别十八讲~系列文章09:AI 算法基础:从传统图像处理到深度学习的视觉“大脑“
图像处理·人工智能·算法·机器视觉·工业智能化·高炉炼铁智能化·高炉智能识别
运维行者_9 小时前
PHP性能监控怎么做?从响应时间到慢函数的6个关键指标
运维·服务器·开发语言·网络·支持向量机·php·接口隔离原则
alphaTao9 小时前
LeetCode 每日一题 2026/9/28-2026/10/4
算法·leetcode
Wang's Blog9 小时前
Java框架 SpringCloud 快速入门: Nacos 配置管理之添加配置与 dataId 命名规范
java·开发语言·spring cloud
源码学社9 小时前
图像去水印实测:OpenCV inpainting vs LaMa,传统算法和 AI 模型差距有多大
人工智能·opencv·算法·去水印·图片水印·ai去水印
阿俊-全栈开发9 小时前
LikeShop单商户Java商城如何从容承接高并发流量?
java·开发语言·spring boot·spring·系统架构
云樱梦海9 小时前
5 分钟上手 IndexTTS 2.5 便携包:不用装 Python、不挑显卡、本地离线跑语音克隆
开发语言·python·tts·indextts2.5