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

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

相关推荐
hsling松子22 分钟前
使用PaddleHub智能生成,献上浓情国庆福
人工智能·算法·机器学习·语言模型·paddlepaddle
dengqingrui1231 小时前
【树形DP】AT_dp_p Independent Set 题解
c++·学习·算法·深度优先·图论·dp
C++忠实粉丝1 小时前
前缀和(8)_矩阵区域和
数据结构·c++·线性代数·算法·矩阵
ZZZ_O^O1 小时前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树
CV-King2 小时前
opencv实战项目(三十):使用傅里叶变换进行图像边缘检测
人工智能·opencv·算法·计算机视觉
代码雕刻家2 小时前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法
雨中rain2 小时前
算法 | 位运算(哈希思想)
算法
吾爱星辰3 小时前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin
ChinaDragonDreamer3 小时前
Kotlin:2.0.20 的新特性
android·开发语言·kotlin
IT良3 小时前
c#增删改查 (数据操作的基础)
开发语言·c#