C语言之归并排序

目录

[一 简介](#一 简介)

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

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

A.时间复杂度:

B.空间复杂度:

C.总结:


一 简介

归并排序(Merge Sort)是一种基于分治策略的高效排序算法,其基本思想是将一个大问题分解为若干个规模较小且相互独立的相同子问题进行解决,然后再合并这些子问题的解以得到原问题的解。在C语言中实现归并排序通常包括两个主要步骤:分解合并

二 代码实现

下面是一个简单的C语言实现归并排序的例子:

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

// 归并操作函数,用于合并两个已排序数组
void merge(int arr[], int l, int m, int r) {
    int i, j, k;
    int n1 = m - l + 1;
    int n2 = r - m;

    // 创建临时数组
    int L[n1], R[n2];

    // 将arr[l...m]复制到L[]中
    for (i = 0; i < n1; i++)
        L[i] = arr[l + i];
    // 将arr[m+1...r]复制到R[]中
    for (j = 0; j < n2; j++)
        R[j] = arr[m + 1 + j];

    // 合并两个有序数组
    i = 0;
    j = 0;
    k = l;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }

    // 将剩余部分复制回原数组
    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }
    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }
}

// 分治法实现归并排序
void mergeSort(int arr[], int l, int r) {
    if (l < r) {
        // 找到中间点
        int m = l + (r - l) / 2;

        // 递归地对左半部分进行归并排序
        mergeSort(arr, l, m);

        // 递归地对右半部分进行归并排序
        mergeSort(arr, m + 1, r);

        // 合并两个已排序的部分
        merge(arr, l, m, r);
    }
}

// 测试归并排序函数
int main() {
    int arr[] = {12, 11, 13, 5, 6, 7};
    int arr_size = sizeof(arr) / sizeof(arr[0]);

    printf("原始数组: \n");
    for (int i = 0; i < arr_size; i++)
        printf("%d ", arr[i]);

    mergeSort(arr, 0, arr_size - 1);

    printf("\n排序后的数组: \n");
    for (int i = 0; i < arr_size; i++)
        printf("%d ", arr[i]);
    
    return 0;
}

在这段代码中:

  • merge 函数负责将两个已经排好序的子数组合并成一个有序数组。
  • mergeSort 函数实现了归并排序的核心逻辑,通过递归不断将待排序数组一分为二,直到子数组只剩下一个元素或者为空,然后调用 merge 函数逐步合并子数组,最终完成整个数组的排序。

三 时空复杂度

归并排序(Merge Sort)的时间复杂度和空间复杂度如下:

A.时间复杂度:

  • 最好情况:无论输入数组是否有序,归并排序的平均和最坏时间复杂度都是相同的。
  • 平均情况 :时间复杂度为 ,其中 n 是待排序数组中的元素数量。这是因为归并排序采用分治策略,每次都将问题规模减半,然后合并两个已排序部分的时间与 n 成线性关系,由于分解次数是 级别的,所以总的时间复杂度为

B.空间复杂度:

  • 额外空间:归并排序需要一个临时数组来合并两个已排序的子数组,这个临时数组的大小与原始数组相同。因此,归并排序的空间复杂度是 O(n)。在递归过程中,每一层递归都会消耗额外空间,但由于这些空间只在合并阶段使用,并且在合并完成后会被释放,故在任意时刻只会有一个临时数组占用内存,其大小最多等于原数组长度。

C.总结:

总结来说,归并排序虽然具有较高的额外空间需求,但它是一种稳定的排序算法,且在所有情况下都能保证 的时间复杂度,适用于大规模数据集的排序任务。

相关推荐
j_xxx404_14 分钟前
LeetCode模拟算法精解II:外观数列与数青蛙
数据结构·c++·算法·leetcode
牢姐与蒯15 分钟前
字符串相乘
算法
得物技术16 分钟前
大禹平台:流批一体离线Dump平台的设计与应用|得物技术
java·后端·算法
轩情吖23 分钟前
MySQL之表的增删查改
android·开发语言·c++·后端·mysql·adb·
这是个栗子26 分钟前
前端开发中的常用工具函数(五)
javascript·数据结构·reduce
2301_7938046927 分钟前
C++与硬件交互编程
开发语言·c++·算法
像污秽一样29 分钟前
算法设计与分析-习题9.2
数据结构·算法·排序算法·dfs
仟濹32 分钟前
【算法打卡day26(2026-03-18 周三)今日算法:「回溯算法」& 蓝桥杯真题(简单题型)】7个
算法·蓝桥杯
csbysj202034 分钟前
jEasyUI 转换 HTML 表格为数据网格
开发语言
历程里程碑37 分钟前
39. 从零实现UDP服务器实战(带源码) V1版本 - Echo server
服务器·开发语言·网络·c++·网络协议·udp·php