当前位置: 首页 > news >正文

归并排序与快速排序的简单实现(C语言)

文章目录

    • 归并排序与快速排序的简单实现(C语言)
      • 一、归并排序实现
        • 核心思想
        • 关键特性
        • C语言实现
      • 二、快速排序实现
        • 核心思想
        • 关键特性
        • C语言实现
      • 三、算法对比分析
    • 四、总结

归并排序与快速排序的简单实现(C语言)

一、归并排序实现

核心思想

采用分治策略的三步走:

  1. 分解:递归将数组二分至单个元素
  2. 解决:单个元素自然有序
  3. 合并:有序子数组合并为完整数组
关键特性
  • 稳定排序(相等元素顺序不变)
  • 时间复杂度:O(n log n)
  • 空间复杂度:O(n)
C语言实现
#include <stdio.h>
#include <stdlib.h>

// 合并两个有序子数组
void merge(int arr[], int left, int mid, int right) {
    int n1 = mid - left + 1;
    int n2 = right - mid;

    // 创建临时数组
    int *L = (int*)malloc(n1 * sizeof(int));
    int *R = (int*)malloc(n2 * sizeof(int));

    // 拷贝数据到临时数组
    for (int i = 0; i < n1; i++)
        L[i] = arr[left + i];
    for (int j = 0; j < n2; j++)
        R[j] = arr[mid + 1 + j];

    // 合并临时数组
    int i = 0, j = 0, k = left;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k++] = L[i++];
        } else {
            arr[k++] = R[j++];
        }
    }

    // 拷贝剩余元素
    while (i < n1) arr[k++] = L[i++];
    while (j < n2) arr[k++] = R[j++];

    free(L);
    free(R);
}

// 递归排序函数
void mergeSort(int arr[], int left, int right) {
    if (left < right) {
        int mid = left + (right - left)/2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid+1, right);
        merge(arr, left, mid, right);
    }
}

二、快速排序实现

核心思想

通过分区操作实现就地排序:

  1. 选基准:选择数组元素作为基准值(pivot)
  2. 分区:将数组分为小于基准和大于基准的两部分
  3. 递归:对子数组重复上述过程
关键特性
  • 平均时间复杂度O(n log n)
  • 最坏情况O(n²)(可通过优化避免)
  • 原地排序(空间复杂度O(log n)
  • 不稳定排序
C语言实现
// 交换两个元素
void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 分区函数(Lomuto方案)
int partition(int arr[], int low, int high) {
    int pivot = arr[high];  // 选择最后一个元素作为基准
    int i = low - 1;  // 小于基准的边界索引

    for (int j = low; j <= high - 1; j++) {
        if (arr[j] <= pivot) {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return i + 1;
}

// 递归排序函数
void quickSort(int arr[], int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}

// 优化版基准选择(三数取中法)
int medianOfThree(int arr[], int low, int high) {
    int mid = low + (high - low)/2;
    if (arr[low] > arr[mid]) swap(&arr[low], &arr[mid]);
    if (arr[low] > arr[high]) swap(&arr[low], &arr[high]);
    if (arr[mid] > arr[high]) swap(&arr[mid], &arr[high]);
    return mid;
}

三、算法对比分析

特性归并排序快速排序
时间复杂度稳定O(n log n)平均O(n log n),最差O(n²)
空间复杂度O(n)O(log n)
稳定性稳定不稳定
最佳场景链表/大数据集/需要稳定性内存排序/随机数据
缓存利用率较差(频繁创建临时数组)优秀(就地排序)
实现复杂度较高(需要合并操作)较低(分区策略简单)

四、总结

「稳链外,选归并;快省效,用快排」

  • 稳(稳定性) / 链(链表) / 外(外部数据) → 归并排序
  • 快(速度) / 省(内存) / 效(效率) → 快速排序

相关文章:

  • 前端自动创建react项目脚手架
  • 中国太平保险网申校招测评笔试真题分析、历年真题题库、北森答案解析
  • golang 日志log与logrus
  • Android开发中的数据结构与算法:树与图
  • 音视频 YUV格式详解
  • Web开发-JS应用微信小程序源码架构编译预览逆向调试嵌套资产代码审计
  • 孤码长征:破译PCL自定义点云注册机制源码迷局——踩坑实录与架构解构
  • grafana 配置页面告警
  • 【LLM】Elasticsearch作为向量库入门指南
  • IDEA 终端 vs CMD:为什么 java -version 显示的 JDK 版本不一致?
  • 电子文档安全管理系统V6.0接口backup存在任意文件下载漏洞
  • golang 的strconv包常用方法
  • J2EE框架技术第八章 SpringMVC框架技术
  • HarmonyOS 介绍
  • Ubuntu在VMware中无法全屏
  • MIPS-32架构(寄存器堆,指令系统,运算器)
  • 网络空间安全(45)PHP入门学习
  • 电影交流|基于Java+vue的电影交流平台小程序系统(源码+数据库+文档)
  • 封装了一个优雅的iOS全屏侧滑返回工具
  • [蓝桥杯 2023 省 A] 网络稳定性
  • 北京网站关键词排名/seo专员工资待遇
  • 海口专门做网站/上海最新新闻热点事件
  • 在网站做登记表备案 如果修改/女生学网络营销这个专业好吗
  • wordpress怎么引用新浪ajax/一键优化免费下载
  • 深圳龙江网站设计/上海排名优化seo
  • 杭州制作网站的公司/成都私人网站制作