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.总结:

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

相关推荐
YL200404263 小时前
048路径总和III
数据结构·dfs
z200509303 小时前
每日简单算法题——————跟着卡尔
算法
踩着两条虫3 小时前
「AI + 低代码」的可视化设计器
开发语言·前端·低代码·设计模式·架构
JoneBB3 小时前
ABAP Webservice连接
运维·开发语言·数据库·学习
即使再小的船也能远航4 小时前
【Python】安装
开发语言·python
Irissgwe4 小时前
类与对象(三)
开发语言·c++·类和对象·友元
️是784 小时前
信息奥赛一本通—编程启蒙(3395:练68.3 车牌问题)
数据结构·c++·算法
Liangwei Lin4 小时前
LeetCode 118. 杨辉三角
算法·leetcode·职场和发展
计算机安禾4 小时前
【c++面向对象编程】第24篇:类型转换运算符:自定义隐式转换与explicit
java·c++·算法
鼠鼠我(‘-ωก̀ )好困4 小时前
leetGPU
算法