归并排序(MergeSort)

  归并排序的核心思想是“分治”(的过程中将问题分解成小问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

  它是一种稳定的排序, 时间复杂度为O(nlogn)

 

  例如要将【8,4,5,7,1,3,6,2】 排序,步骤如下图

  

 

  分的过程中调用递归函数,将其拆分成许多小的部分,直到只剩一个元素停止拆分,开始治的过程

  治的时候需要定义一个temp数组,将左右两部分合并的内容存储在里面

  使用两个指针,分别指向左边第一个位置和右边第一个位置,比较它们在数组中的大小  值小的下标往后移一位,值大的不变

  下面是【4,5,7,8】和【1,2,3,6】合并的过程

  

 

  代码如下:

       static void Main(string[] args)
        {
            int[] arr = new int[] { 2, 5, 7, 3, 8, 4, 9, 1 };
            MergeSort(arr, 0, arr.Length - 1);
        }    

        private static void MergeSort(int[] arr, int left, int right)
        {
            //left == right 说明只有一个元素  返回
            if (left == right) return;

            int mid = (left + right) / 2;

            MergeSort(arr, left, mid);
            MergeSort(arr, mid + 1, right);

            Merge(arr, left, mid, right);
        }

        private static void Merge(int[] arr, int left, int mid, int right)
        {
            int[] temp = new int[right - left + 1];
            //lStart:左边第一个元素    rStart:右边第一个元素
            int lStart = left, rStart = mid + 1;
            //help数组下标
            int index = 0;

            while(lStart<=mid && rStart <= right)
            {
                //两个下标都没有越界,将help数组中填入他们中较小的数  并且下标右移
                temp[index++] = arr[lStart] < arr[rStart] ? arr[lStart++] : arr[rStart++];
            }

            //如果左边有剩下的,将他直接复制到help数组里面
            while (lStart <= mid)
            {
                temp[index++] = arr[lStart++];
            }

            //如果右边有剩下的,将他直接复制到help数组里面(和上面的while只会执行一个)
            while (rStart <= right)
            {
                temp[index++] = arr[rStart++];
            }

            //将help数组的内容复制到arr的对应位置
            Array.Copy(temp, 0, arr, left, index);
        }
MergeSort

 

注:图片来源

  作者: dreamcatcher-cx

  出处: <http://www.cnblogs.com/chengxiao/>

posted @ 2020-04-15 16:08  天份&  阅读(317)  评论(0编辑  收藏  举报