C# 归并排序 的原理及代码实现

题外话: 哦豁,一天肝4章,可以啊你小子


1.什么是归并排序

  • 两个或两个以上的有序子序列,归并为一个有序序列
  • 你可以理解为, 初中的时候上手工课,老师说2个同学一组;
    • 我们每2个人作为一个组合,选出一个最佳作品;
    • 然后老师又说:每两个组合合并为一个4人组合,再选出一个最佳作品;
    • 再来,每两个组合再次合并为一个8人组合,直到选出一个最优秀的作品。

PS: 上面的例子并不严谨,只是让你了解“合并”这个过程


2. 2-路归并排序

  • 什么是2-路归并排序?
    • 上面说到,归并排序是“2个或2个以上的序列xxxxx”;
    • 那么我们只选择2个序列2个序列合并,那么就是2-路归并排序
  • 图片解释
    在这里插入图片描述

3. 2-路归并排序代码实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace YoyoCode
{
    
    
    internal class MSort
    {
    
    
        //辅助数组
        static int[] sArray;
        /// <summary>
        /// 归并排序
        /// </summary>
        /// <param name="pArray">需要排序的数组</param>
        public static void MergeSort(int[] pArray)
        {
    
    
            //辅助数组的初始化
            sArray = new int[pArray.Length];
            //步长限制1、2、4、8、16...
            //如果数组长度为9,最大步长不能为4,必须是8
            //因为8和剩下的一个元素需要合并
            for (int step = 1; step < pArray.Length; step *= 2)
            {
    
    
                //在步长限制下,对数组的两两归并
                for (int j = 0; j < pArray.Length - step; j += step + step)
                {
    
    
                    Merge(pArray, j, j + step - 1, Math.Min(j + step + step - 1, pArray.Length - 1));
                }
            }
        }
        /// <summary>
        /// 对两个子数组进行排序
        /// </summary>
        /// <param name="pArray">数组</param>
        /// <param name="low">子数组1的起始index</param>
        /// <param name="mid">子数组1的终止index,mid+1就是子数组2的起始index</param>
        /// <param name="high">子数组2的终止index</param>
        private static void Merge(int[] pArray, int low, int mid, int high)
        {
    
    
            //辅助数组赋值
            for (int k = low; k <= high; k++)
            {
    
    
                sArray[k] = pArray[k];
            }
            //合并
            int i = low; 
            int j = mid + 1;
            for (int k = low; k <= high; k++)
            {
    
    
                //越界直接合并
                if (i > mid)
                {
    
    
                    pArray[k] = sArray[j++];
                }
                else if (j > high)
                {
    
    
                    pArray[k] = sArray[i++];
                }
                else
                {
    
    
                    //没越界则比较,两者中小的放进结果中
                    if (sArray[i] < sArray[j])
                    {
    
    
                        pArray[k] = sArray[i++];
                    }
                    else
                    {
    
    
                        pArray[k] = sArray[j++];
                    }
                }
            }
        }
    }
}

说明: 都在酒里,啊不是,都在注释里了,看注释读一遍,再跟着手搓一边就明白原理了,看着恶心而已~


4.算法分析

  • 时间复杂度
    • O(nlogn)
  • 空间复杂度
    • O(n)
  • 算法稳定性
    • 稳定


结束语: 好累呀好累呀好累呀

猜你喜欢

转载自blog.csdn.net/Liyager/article/details/129210461