C#归并排序算法

举报
Rolle 发表于 2024/10/31 00:04:53 2024/10/31
【摘要】 归并排序(Merge Sort)是一种高效的排序算法,采用分治法(Divide and Conquer)的一个典型应用。这个算法在1945年由John von Neumann首次提出。与其它排序算法,如快速排序不同,归并排序无论在最好、最坏还是平均情况下,时间复杂度都是O(n log n),这使得它在大数据集上非常有效。归并排序是建立在归并操作上的一种稳定的排序算法,该算法将已有序的子序列合...

归并排序(Merge Sort)是一种高效的排序算法,采用分治法(Divide and Conquer)的一个典型应用。这个算法在1945年由John von Neumann首次提出。与其它排序算法,如快速排序不同,归并排序无论在最好、最坏还是平均情况下,时间复杂度都是O(n log n),这使得它在大数据集上非常有效。归并排序是建立在归并操作上的一种稳定的排序算法,该算法将已有序的子序列合并,得到完全有序的序列。

归并排序的基本原理
归并排序的基本思想是:将两个已经排序的序列合并成一个排序的序列,即叫归并操作。如果待排序序列中共有n个元素,我们可以将序列任意分成两半,然后对序列的两半分别进行归并排序,最后将两个已排序的半序列进行归并。

归并排序的算法步骤
将序列任意分成两半。
对序列的两半分别进行归并排序。
将两个已排序的半序列进行归并,得到排序好的完整序列。
归并排序的C#实现
下面是一个归并排序算法的C#实现示例:
using System;

class Program
{
// 归并排序
static void MergeSort(int[] arr, int left, int right)
{
if (left < right)
{
// 找到中间位置
int middle = left + (right - left) / 2;

        // 分别对左右两半进行归并排序
        MergeSort(arr, left, middle);
        MergeSort(arr, middle + 1, right);

        // 合并两个已排序的半序列
        Merge(arr, left, middle, right);
    }
}

// 合并两个有序序列
static void Merge(int[] arr, int left, int middle, int right)
{
    // 临时数组
    int n1 = middle - left + 1;
    int n2 = right - middle;

    int[] L = new int[n1];
    int[] R = new int[n2];

    // 拷贝数据到临时数组 L[] 和 R[]
    for (int i = 0; i < n1; i++)
        L[i] = arr[left + i];
    for (int j = 0; j < n2; j++)
        R[j] = arr[middle + 1 + j];

    // 合并临时数组回到原数组
    int i = 0; // 初始化第一个子数组的索引
    int j = 0; // 初始化第二个子数组的索引
    int k = left; // 初始化合并后数组的索引

    while (i < n1 && j < n2)
    {
        if (L[i] <= R[j])
        {
            arr[k] = L[i];
            i++;
        }
        else
        {
            arr[k] = R[j];
            j++;
        }
        k++;
    }

    // 拷贝 L[] 的剩余元素
    while (i < n1)
    {
        arr[k] = L[i];
        i++;
        k++;
    }

    // 拷贝 R[] 的剩余元素
    while (j < n2)
    {
        arr[k] = R[j];
        j++;
        k++;
    }
}

static void Main()
{
    int[] arr = { 12, 11, 13, 5, 6, 7 };
    int n = arr.Length;

    Console.WriteLine("Given array is ");
    foreach (int value in arr)
    {
        Console.Write(value + " ");
    }

    MergeSort(arr, 0, n - 1);

    Console.WriteLine("\nSorted array is ");
    foreach (int value in arr)
    {
        Console.Write(value + " ");
    }
}

}
在这个示例中,我们首先定义了一个未排序的整数数组arr。然后,我们使用MergeSort方法对数组进行排序。MergeSort方法采用递归的方式,将数组分成两半,直到每半只有一个元素,然后使用Merge方法将两个有序的半序列合并成一个完整的有序序列。

归并排序的性能分析
归并排序的平均和最坏情况时间复杂度都是O(n log n),其中n是数组的长度。这是因为归并排序需要进行对数级别的分割和线性级别的合并。在最好的情况下,归并排序的时间复杂度也是O(n log n),因为它仍然需要进行相同的分割和合并步骤。

归并排序的空间复杂度是O(n),因为它需要一个额外的存储空间来存储临时数组。

归并排序的优化
尽管归并排序的空间复杂度较高,但我们可以通过一些技巧来优化它。例如,我们可以使用原地归并排序来减少额外的存储空间需求,或者使用多线程来加速排序过程。

下面是一个原地归并排序算法的C#实现示例:
using System;

class Program
{
// 原地归并排序
static void InPlaceMergeSort(int[] arr, int left, int right)
{
if (left < right)
{
int middle = left + (right - left) / 2;

        InPlaceMergeSort(arr, left, middle);
        InPlaceMergeSort(arr, middle + 1, right);

        InPlaceMerge(arr, left, middle, right);
    }
}

// 原地合并两个有序序列
static void InPlaceMerge(int[] arr, int left, int middle, int right)
{
    int n1 = middle - left + 1;
    int n2 = right - middle;

    int i = left, j = middle + 1, k = left;

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

    while (i <= middle)
    {
        arr[k++] = arr[i++];
    }

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

static void Main()
{
    int[] arr = { 12, 11, 13, 5, 6, 7 };
    int n = arr.Length;

    Console.WriteLine("Given array is ");
    foreach (int value in arr)
    {
        Console.Write(value + " ");
    }

    InPlaceMergeSort(arr, 0, n - 1);

    Console.WriteLine("\nSorted array is ");
    foreach (int value in arr)
    {
        Console.Write(value + " ");
    }
}

}
在这个优化后的示例中,我们引入了原地合并的方法InPlaceMerge,以减少额外的存储空间需求。

归并排序的应用场景
归并排序适用于大规模数据的排序,特别是当数据存储在数组或链表中时。由于归并排序的稳定性和对大数据集的高效性,它在数据库和文件系统中的排序操作中非常常见。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。