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日

相关文章

  • python 如何在list中找Topk的数值和索引

    对于如何在Python的list中找Topk的数值和索引,可以采用以下方法: 方法一:使用sorted函数排序 可以使用Python内置的sorted函数对list进行排序,然后取前k个元素,同时得到它们的索引。具体代码如下: lst = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] k = 3 # 记录每个元素的索引和值 lst_wi…

    算法与数据结构 2023年5月19日
    00
  • Java的Arrays.sort()方法排序算法实例分析

    Java的Arrays.sort()方法排序算法实例分析 在Java中,我们可以使用Arrays.sort()方法对数组进行排序。这个方法具有良好的性能和适应性。 然而,不了解其实现原理可能会产生些困惑,我们在这里将从排序算法本身的角度,详细讲述如何使用Arrays.sort()方法并提高其性能。 排序算法 Arrays.sort()方法使用的排序算法是不稳…

    算法与数据结构 2023年5月19日
    00
  • C语言 实现归并排序算法

    C语言实现归并排序算法的攻略如下: 展示归并排序算法思路 先将待排序的序列拆分成若干小规模子序列,直到每个子序列可以直接排序为止。 然后对每个子序列进行排序,合并成新的有序序列。 重复第二步,直到只剩下一个排序完毕的序列。 C语言代码实现 下面是一份C语言实现归并排序算法的代码,代码内部有详细的注释,可以帮助理解代码: #include <stdio.…

    算法与数据结构 2023年5月19日
    00
  • golang 归并排序,快速排序,堆排序的实现

    Golang 实现归并排序,快速排序和堆排序 简介 排序算法的实现是大多数程序员必备的技能之一。在这个过程中,我们考虑三种经典的排序算法之一:归并排序,快速排序和堆排序。我们在学习它们的同时,也在学习使用 Golang 写出高效的排序算法。 归并排序 算法原理 归并排序是基于归并操作的一种排序算法,该算法的核心思想是将一个数组分成两个较小的数组,然后递归地将…

    算法与数据结构 2023年5月19日
    00
  • java 排序算法之快速排序

    Java 排序算法之快速排序 快速排序(Quick Sort)是一种高效的排序算法,属于分治法(Divide and Conquer)策略,它的时间复杂度为 $O(nlogn)$,在大多数情况下可以达到线性级别的时间复杂度,是非常重要且常用的排序算法之一。 基本思想 快速排序算法的基本思路是:选择一个元素作为数组的 “基准”(pivot),将小于基准的元素放…

    算法与数据结构 2023年5月19日
    00
  • 深入理解JS实现快速排序和去重

    深入理解JS实现快速排序和去重 1.快速排序 快速排序是一种快速并且高效的排序算法。下面是快速排序的步骤: 选择数组中的中心元素作为基准点(pivot) 将所有小于基准点的元素移到基准点的左侧,所有大于基准点的元素移到基准点的右侧 对左右两个子数组递归执行步骤1和步骤2,直到子数组长度为1或0 快速排序可以用以下的JavaScript代码来实现: funct…

    算法与数据结构 2023年5月19日
    00
  • js算法中的排序、数组去重详细概述

    JS算法中的排序、数组去重详细概述 排序算法 在JavaScript中,常用的排序算法有冒泡排序、插入排序、选择排序、快速排序等。下面将分别对他们进行介绍。 冒泡排序 冒泡排序是一种稳定的排序算法,它的基本思想是从左到右依次比较相邻两个元素的大小,并且将较大的元素向右移动,较小的元素向左移动。重复这个过程直到没有任何元素需要移动为止。 下面是冒泡排序的Jav…

    算法与数据结构 2023年5月19日
    00
  • C++实现希尔排序(ShellSort)

    下面是关于C++实现希尔排序(ShellSort)的攻略。 什么是希尔排序? 希尔排序是插入排序的一种改进版本,与普通插入排序不同的是,它会先将数组按一定间隔 gap 分成若干个小组进行插入排序,然后缩小间隔再分组排序,直到最后 gap 为 1,此时整个序列就是有序的。希尔排序的本质就是分组的插入排序。 希尔排序的代码实现 下面针对希尔排序的核心代码进行讲解…

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