C语言实现排序算法之归并排序详解

C语言实现排序算法之归并排序详解

概述

归并排序是一种分治算法,在处理大规模数据排序时具有较高的效率。该算法将要排序的数组分为两部分,对每个部分内部进行排序,然后将排好序的两部分合并成一个有序数组。该算法在实现时需要借助递归和迭代两种方式。

步骤

归并排序可递归或迭代实现。以下是递归实现的步骤:

  1. 分解:将待排序数组分为两个等长的子数组,分别为左半部分和右半部分。
  2. 解决:对左半部分和右半部分分别调用归并排序函数进行递归排序。
  3. 合并:将已排好序的两个子数组进行合并,得到完整的排好序的数组。

以下是迭代实现的步骤:

  1. 初始时,将待排序数组看成n个只有一个元素的子序列,对每个子序列都进行归并排序。
  2. 将排序后的后续序列按照由小到大顺序依次合并,直到得到完整的排好序数组。

代码实现

以下是C语言实现归并排序的代码示例,包括递归和迭代两种实现方式:

递归实现

void merge_sort_recursive(int arr[], int reg[], int start, int end)
{
    if (start >= end) {
        return;
    }

    int len = end - start, mid = (len >> 1) + start;
    int start1 = start, end1 = mid;
    int start2 = mid + 1, end2 = end;
    merge_sort_recursive(arr, reg, start1, end1);
    merge_sort_recursive(arr, reg, start2, end2);

    int k = start;
    while (start1 <= end1 && start2 <= end2)
        reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
    while (start1 <= end1)
        reg[k++] = arr[start1++];
    while (start2 <= end2)
        reg[k++] = arr[start2++];

    for (k = start; k <= end; k++)
        arr[k] = reg[k];
}

迭代实现

void merge_sort_iterative(int arr[], int len)
{
    int* a = arr;
    int* b = (int*)malloc(len * sizeof(int));
    int seg, start;

    for (seg = 1; seg < len; seg += seg) {
        for (start = 0; start < len; start += seg + seg) {
            int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);
            int k = low;
            int start1 = low, end1 = mid;
            int start2 = mid, end2 = high;

            while (start1 < end1 && start2 < end2)
                b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
            while (start1 < end1)
                b[k++] = a[start1++];
            while (start2 < end2)
                b[k++] = a[start2++];
        }
        int* temp = a;
        a = b;
        b = temp;
    }
    if (a != arr) {
        int i;
        for (i = 0; i < len; i++)
            b[i] = a[i];
        b = a;
    }
    free(b);
}

示例说明

假设有如下数组需要进行排序:

{10, 38, 19, 2, 45, 5, 3, 1, 22, 15}

递归实现示例

首先使用递归方法进行排序,调用 merge_sort_recursive() 函数进行排序。将原数组 arr[] 复制一份,作为临时存储数组 reg[]。左半部分排序时,将起始下标设置为 start1,终止下标设置为 mid,右半部分排序时,将起始下标设置为 mid+1,终止下标设置为 end。分别对左右两半部分调用 merge_sort_recursive()函数进行递归排序。排序完成后,将 reg[] 中已排好序的数组合并,之后再将 reg[] 的值复制到 arr[] 中。

以下是示例代码:

int main()
{
    int arr[] = { 10, 38, 19, 2, 45, 5, 3, 1, 22, 15 };
    int len = sizeof(arr) / sizeof(arr[0]);

    int* reg = (int*)malloc(len * sizeof(int));

    merge_sort_recursive(arr, reg, 0, len - 1);

    free(reg);

    return 0;
}

迭代实现示例

接下来使用迭代方法进行排序,调用 merge_sort_iterative() 函数进行排序。将数组看成 n 个只有一个元素的子序列,对每个子序列的进行调用 merge_sort_iterative() 函数进行排序。之后将排好序的子序列依次两两合并,直到得到完整排好序的数组。

以下是示例代码:

int main()
{
    int arr[] = { 10, 38, 19, 2, 45, 5, 3, 1, 22, 15 };
    int len = sizeof(arr) / sizeof(arr[0]);

    merge_sort_iterative(arr, len);

    return 0;
}

总结

归并排序是一种典型的分治思想的排序算法。无论是递归还是迭代实现都需要对排序数组按照规则进行分裂,之后对子数组进行排序合并。这种算法的优点是可以对排序数组保证稳定性,以及在处理大规模排序数据时具有较高的效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现排序算法之归并排序详解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 算法系列15天速成 第一天 七大经典排序【上】

    我会为你详细讲解“算法系列15天速成 第一天 七大经典排序【上】”的完整攻略。 标题 算法系列15天速成 第一天 七大经典排序【上】 内容 本文主要介绍了常用的七大经典排序算法,分别是插入排序、希尔排序、选择排序、冒泡排序、快速排序、归并排序以及堆排序。对每个算法的特点、实现过程和时间复杂度进行了详细的讲解,同时也对每个算法进行了简单的示例说明。 插入排序 …

    算法与数据结构 2023年5月19日
    00
  • JavaScript算法学习之冒泡排序和选择排序

    JavaScript算法学习之冒泡排序和选择排序 冒泡排序和选择排序是常见的两种排序算法。在本文中,我们将详细讲解这两种排序算法,并提供代码示例供读者参考。 冒泡排序 冒泡排序是一种简单的排序算法,它通过比较相邻两个元素的大小,依次将最大的元素冒泡到数组的末尾。 以下是冒泡排序的代码示例: function bubbleSort(array) { const…

    算法与数据结构 2023年5月19日
    00
  • javascript使用递归算法求两个数字组合功能示例

    下面是关于 JavaScript 使用递归算法求两个数字组合的完整攻略: 什么是递归? 递归是一种思想,用来解决一些需要重复执行的问题,比如求一个数的阶乘,求一个斐波那契数列等。通俗的讲,递归就是函数自己调用自己。 递归的使用场景 递归通常用于解决以下两类问题: 包含自相似性质的问题,如分形图形。 对于可被拆分为相同问题的大型问题。 求两个数字组合的递归方案…

    算法与数据结构 2023年5月19日
    00
  • Java中自然排序和比较器排序详解

    Java中自然排序和比较器排序详解 简介 Java中排序分为自然排序和比较器排序两种方式。当对象包含了Comparable接口实现的compareTo方法时,便支持了自然排序。而比较器排序则需要自己实现一个Comparator接口,并传入调用方法中。本文将从以下几个方面详细介绍这两种排序方式: Comparable接口及compareTo方法 Compara…

    算法与数据结构 2023年5月19日
    00
  • Java中sort排序函数实例详解

    Java中sort排序函数实例详解 在Java中,Sort排序函数可以对数组进行排序,它是Java内置的一个排序函数。通过使用这个函数,可以快速、方便地对数组进行排序。 Syntax 以下是sort函数的语法: public static void sort(int[] arr) 其中arr是要排序的数组。 Parameters 以下是sort函数的参数: …

    算法与数据结构 2023年5月19日
    00
  • java冒泡排序和选择排序详解

    Java冒泡排序和选择排序详解 冒泡排序 冒泡排序是最简单的排序算法之一,也是入门学习排序算法的基础。该算法的主要思路是从最后一个元素开始,与前面一个元素比较并交换,直到最终将最小元素移动到第一个位置。 冒泡排序实现原理 冒泡排序算法每一轮比较都会将相邻元素中较大或较小的一个元素“冒泡”到待排序序列的最后一个位置。类似于鸡尾酒中的冒泡,所以也叫做“鸡尾酒排序…

    算法与数据结构 2023年5月19日
    00
  • C++实现堆排序示例

    下面就详细讲解一下“C++实现堆排序示例”的完整攻略。 什么是堆排序 堆排序是一种树形选择排序方法,它是通过将待排序的序列构建成一个堆,在堆中,全局最大或最小的元素总是位于根节点,根节点最大或最小的元素会被输出到一个新的序列中,再将剩余的元素重新构建成堆进行下一轮循环,直到所有元素均被输出为止。 实现步骤 堆排序主要有两个步骤:构建堆和调整堆。 构建堆 将待…

    算法与数据结构 2023年5月19日
    00
  • C#归并排序的实现方法(递归,非递归,自然归并)

    下面是关于C#归并排序的实现方法的完整攻略: 什么是归并排序? 归并排序是一种基于分治法的算法,具体实现方法是将原序列分成若干个子序列,分别进行排序,然后将排好序的子序列合并成一个大的有序序列。 递归实现归并排序 递归实现归并排序分为三步: 分解数组:将要排序的数组从中间分成两个部分,即分为左右两个子数组。这里使用数组下标来实现。 递归排序子数组:对分解出来…

    算法与数据结构 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部