C#归并排序的实现方法(递归,非递归,自然归并)

下面是关于C#归并排序的实现方法的完整攻略:

什么是归并排序?

归并排序是一种基于分治法的算法,具体实现方法是将原序列分成若干个子序列,分别进行排序,然后将排好序的子序列合并成一个大的有序序列。

递归实现归并排序

递归实现归并排序分为三步:

  1. 分解数组:将要排序的数组从中间分成两个部分,即分为左右两个子数组。这里使用数组下标来实现。

  2. 递归排序子数组:对分解出来的左右两个子数组分别调用递归函数,重复第1步和第2步。

  3. 合并两个有序子数组:将两个排好序的子数组合并成一个有序的数组。

以下是递归实现归并排序的代码片段:

void MergeSort(int[] arr, int left, int right)
{
    if (left >= right)
        return;

    int mid = (left + right) / 2;
    MergeSort(arr, left, mid);
    MergeSort(arr, mid + 1, right);
    Merge(arr, left, mid, right);
}

void Merge(int[] arr, int left, int mid, int right)
{
    int[] tmp = new int[right - left + 1];//辅助数组

    int i = left, j = mid + 1, k = 0;//i和j分别表示两个子数组的起始位置,k表示tmp的起始位置

    while (i <= mid && j <= right)
    {
        if (arr[i] <= arr[j])
            tmp[k++] = arr[i++];
        else
            tmp[k++] = arr[j++];
    }

    while (i <= mid)
        tmp[k++] = arr[i++];

    while (j <= right)
        tmp[k++] = arr[j++];

    for (int p = 0; p < tmp.Length; p++)
        arr[left + p] = tmp[p];//将排好序的辅助数组中的数据复制回原数组
}

非递归实现归并排序

非递归实现归并排序使用迭代的方式,将数组划分成多个小的块,然后将每个小块排序,随后在已排序的各个小块之间进行合并,直到整个数组有序。

以下是非递归实现归并排序的代码片段:

void MergeSort(int[] arr)
{
    int len = arr.Length;
    int blockSize = 1;//块大小

    while (blockSize < len)
    {
        int left = 0;
        while (left + blockSize < len)
        {
            Merge(arr, left, left + blockSize - 1, Math.Min(left + 2 * blockSize - 1, len - 1));
            left += 2 * blockSize;
        }
        blockSize *= 2;
    }
}

void Merge(int[] arr, int left, int mid, int right)
{
    int[] tmp = new int[right - left + 1];

    int i = left, j = mid + 1, k = 0;

    while (i <= mid && j <= right)
    {
        if (arr[i] <= arr[j])
            tmp[k++] = arr[i++];
        else
            tmp[k++] = arr[j++];
    }

    while (i <= mid)
        tmp[k++] = arr[i++];

    while (j <= right)
        tmp[k++] = arr[j++];

    for (int p = 0; p < tmp.Length; p++)
        arr[left + p] = tmp[p];
}

自然归并排序

自然归并排序是一种针对初始序列有序程度较高的序列排序算法。例如一段序列有两个、三个或多个有序片段时,只需对这些有序片段进行归并就能得到有序的最终序列。

以下是自然归并排序的代码片段:

void MergeSort(int[] arr)
{
    int len = arr.Length;
    int[] tmp = new int[len];

    while (true)
    {
        int i = 0;
        while (i < len - 1 && arr[i] <= arr[i + 1])
            i++;

        if (i == len - 1)//整个序列已有序,结束排序
            break;

        int left = i++;//left是分段的左端点
        while (i < len - 1 && arr[i] <= arr[i + 1])
            i++;

        int mid = i;//mid是分段的中间点
        i++;

        int right = i;//right是分段的右端点
        Merge(arr, tmp, left, mid, right);
    }
}

void Merge(int[] arr, int[] tmp, int left, int mid, int right)
{
    int i = left, j = mid, k = 0;

    while (i < mid && j < right)
    {
        if (arr[i] <= arr[j])
            tmp[k++] = arr[i++];
        else
            tmp[k++] = arr[j++];
    }

    while (i < mid)
        tmp[k++] = arr[i++];

    while (j < right)
        tmp[k++] = arr[j++];

    for (int p = 0; p < k; p++)
        arr[left + p] = tmp[p];
}

示例说明

假设有一个数组arr,其中元素为{6, 1, 2, 3, 4, 5},下面分别以递归、非递归和自然归并排序的方式将其排序。

递归实现

int[] arr = { 6, 1, 2, 3, 4, 5 };
MergeSort(arr, 0, arr.Length - 1);
Console.WriteLine(string.Join(" ", arr));

输出结果为:1 2 3 4 5 6

非递归实现

int[] arr = { 6, 1, 2, 3, 4, 5 };
MergeSort(arr);
Console.WriteLine(string.Join(" ", arr));

输出结果为:1 2 3 4 5 6

自然归并排序

int[] arr = { 6, 1, 2, 3, 4, 5 };
MergeSort(arr);
Console.WriteLine(string.Join(" ", arr));

输出结果为:1 2 3 4 5 6

以上就是关于C#归并排序的实现方法的完整攻略,希望对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#归并排序的实现方法(递归,非递归,自然归并) - Python技术站

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

相关文章

  • 设计师灵感来源 细数上市公司LOGO背后的含义

    设计师灵感来源 作为设计师,找灵感是创作过程中的一项重要任务,而且好的设计往往都来自于深度的思考和充足的灵感。那么,设计师在哪里寻找灵感呢? 灵感来源 1. 观察 设计师可以通过观察日常生活中的事物来获取灵感,例如自然风光、建筑、图形等。观察中的选择与细节是关键,需要有敏锐的观察力和审美能力。 2. 学习 学习可以让设计师积累更多知识与思想,这也为他们提供了…

    算法与数据结构 2023年5月19日
    00
  • php自定义二维数组排序函数array_orderby用法示例

    首先,让我们了解一下什么是“数组排序函数”以及“自定义排序函数”。 数组排序函数是指一些用来对数组排序的函数,例如sort()和asort()。自定义排序函数则是指我们可以根据自己的需求来编写一个排序函数,然后通过函数名传递给排序函数,让它按照我们自己的规则进行排序。 在PHP中,有一个函数array_orderby()可以帮助我们实现自定义排序功能。以下是…

    算法与数据结构 2023年5月19日
    00
  • 大数据情况下桶排序算法的运用与C++代码实现示例

    桶排序算法是一种基于计数的排序算法,它的主要思想是把一组数据分成多个桶,对每个桶中的数据进行排序,最后依次把每个桶中的数据合并起来,得到排序后的结果。在大数据情况下,桶排序算法可以大幅减少排序时间,因为它可以快速地将数据分成多个桶,进行并行排序,最终合并起来。 以下是桶排序算法在大数据情况下的运用及C++代码示例: 算法思路 先确定桶的数量,也就是需要将数据…

    算法与数据结构 2023年5月19日
    00
  • 排序算法图解之Java插入排序

    首先要了解什么是插入排序,插入排序是排序算法中简单直观的一种,其原理是将未排序的元素一个一个插入到已经排好序的元素中,最终得到一个有序的序列。那么下面我将用Java代码来演示插入排序的实现过程,并且提供详细的注释帮助读者理解。 算法步骤 从第一个元素开始,认为第一个元素是已经排好序的,取第二个元素和已排序的元素进行比较,如果第二个元素比已排序的元素小,则交换…

    算法与数据结构 2023年5月19日
    00
  • C++实现快速排序(Quicksort)算法

    C++实现快速排序(Quicksort)算法 快速排序(Quicksort)算法是一种常见的排序算法,具有快速、高效、稳定性好等特点,广泛应用于各种工程实践中。 快速排序的基本思想 快速排序的基本思想是:选取一个基准值(pivot),将待排序序列划分成左右两个子序列,左边的子序列中所有元素都不大于基准值,右边的子序列中所有元素都不小于基准值,然后对左右两个子…

    算法与数据结构 2023年5月19日
    00
  • C C++算法题解LeetCode1408数组中的字符串匹配

    C C++算法题解LeetCode1408数组中的字符串匹配 问题描述 给定字符串数组 words,在其中找到两个不同的单词,使得它们的长度之和最长。可以假设 words 中至少存在两个单词。 返回两个单词长度之和的最大值。 解题思路 方法一:暴力枚举 我们可以将字符串数组中的字符串两两组合,计算它们的长度之和并更新最大值,最后返回最大值即可。 时间复杂度:…

    算法与数据结构 2023年5月19日
    00
  • JavaScript插入排序算法原理与实现方法示例

    JavaScript插入排序算法原理与实现方法示例 算法原理 插入排序是一种简单直观的排序算法,其基本原理是将一个待排序的数组依次插入一个有序的数组中,使得最终生成的有序数组是全局有序的。每次将一个待排序的元素插入到有序数组中时,我们从有序数组的末尾开始比较,如果待排序的元素比当前比较的元素小,则交换位置,继续比较,否则插入到当前位置。 实现方法 下面是Ja…

    算法与数据结构 2023年5月19日
    00
  • 堆排序原理及算法代码详解

    堆排序原理及算法代码详解 堆排序属于一种选择排序,它的基本思想是利用堆这种数据结构来进行排序。 堆的概念 堆(Heap)是一个特殊的树形数据结构,它有以下两种类型: 大根堆:每个节点的值都大于或等于其左右孩子节点的值。 小根堆:每个节点的值都小于或等于其左右孩子节点的值。 通过对堆进行操作,可以得到堆排序算法。 堆排序的基本思想 将待排序序列构造成一个大根堆…

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