zoukankan      html  css  js  c++  java
  • C#数据结构与算法系列(二十三):归并排序算法(MergeSort)

    1.介绍

    归并排序(MergeSort)是利用归并的思想实现的排序方法,该算法采用经典的分治策略(分治法将问题分(divide)成一些小的问题然后递归求解,

    而治(conquer)的阶段则将分的阶段得到的各答案“修补”在一起,即分而治之)

    2.示意图

     说明:可以看到这种结构很像一颗完全二叉树,可以采用递归和循环迭代的方式去实现,分阶段可以理解为就是递归拆分子序列的过程

    合并相邻有序子序列

    再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,

    要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤

     

     

     3.实例

    把数组[8,4,5,7,1,3,6,2]使用归并排序完成排序

        public class MergeSort
        {
            public static void Test()
            {
                int[] arr = { 8, 4, 5, 7, 1, 3, 6, 2 };
    
                int[] temp = new int[arr.Length];
    
                Sort(arr,0,arr.Length-1,temp);
    
                Console.WriteLine(string.Join(",",arr));
            }
    
            /// <summary>
            /// 分+合方法
            /// </summary>
            /// <param name="arr"></param>
            /// <param name="left"></param>
            /// <param name="right"></param>
            /// <param name="temp"></param>
            private static void  Sort(int[]  arr,int left,int right,int[] temp)
            {
                if (left<right)
                {
                    //中间索引
                    int mid = (left + right) / 2;
    
                    //向左递归进行分解
                    Sort(arr, left, mid, temp);
    
                    //向右递归进行分解
                    Sort(arr, mid + 1, right, temp);
    
                    //到合并
                    Merge(arr,left,mid,right,temp);
                }
            }
    
            /// <summary>
            /// 合并方法
            /// </summary>
            /// <param name="arr">排序的原始数组</param>
            /// <param name="left">左边有序序列的初始索引</param>
            /// <param name="mid">中间索引</param>
            /// <param name="right">右边索引</param>
            /// <param name="temp">做中转数组</param>
            private static void Merge(int[] arr, int left, int mid, int right, int[] temp)
            {
                int i = left; //初始化i,左边有序序列的初始化索引
    
                int j = mid + 1; //初始化j,右边有序序列的初始化索引
    
                int t = 0; //指向temp数组的当前索引
    
                //(一)
                //先把左右两边(有序)的数据按照规则填充到temp数组
                //直到左右两边的有序序列,有一边处理完成为止
                while (i <= mid && j <= right)
                {
                    //如果左边的有序序列的当前元素,小于或者等于右边有序序列的当前元素
                    //即将左边的当前元素,填充到temp数组
                    //然后t++,i++
                    if (arr[i] <= arr[j])
                    {
                        temp[t] = arr[i];
    
                        t += 1;
    
                        i += 1;
                    }
                    //反之,将右边有序序列的当前元素,填充到temp数组
                    else
                    {
                        temp[t] = arr[j];
    
                        t++;
    
                        j++;
                    }
                }
                //(二)
                //把有剩余数据的一边的数据依次全部填充到temp
                while (i <= mid)
                {
                    //左边的有序序列还有剩余的元素,就全部填充到temp
                    temp[t] = arr[i];
    
                    t++;
    
                    i++;
                }
    
                while (j <= right)
                {
                    temp[t] = arr[j];
    
                    t++;
    
                    j++;
                }
                //(三)
                //将temp数组的元素拷贝到arr,并不是每次都拷贝所有
                t = 0;
    
                int tempLeft = left;
    
                while (tempLeft <= right) //第一次合并 tempLeft=0,right=1 第二次 tempLeft=2 right=3; 
                {
                    arr[tempLeft] = temp[t];
    
                    t++;
    
                    tempLeft++;
                }
    
            }
        }

    结果图

  • 相关阅读:
    用Python完成一个汇率转换器
    鸿蒙如何用JS开发智能手表App
    鸿蒙如何用JS开发智能手表App
    SAP Spartacus SplitViewComponent Migration 的一个具体例子
    SAP Spartacus B2B 页面 Popover Component 的条件显示逻辑
    SAP Spartacus 升级时关于 schematics 的更新
    SAP Spartacus B2B 页面 Disable 按钮的显示原理
    SAP Spartacus B2B 页面 Disable Confirmation 对话框的显示原理
    通过 Feature Level 动态控制 SAP Spartacus 的页面显示
    SAP Commerce Cloud Build Manifest Components
  • 原文地址:https://www.cnblogs.com/vic-tory/p/13327052.html
Copyright © 2011-2022 走看看