• 【经典算法】第六回:归并排序


    1.概述

    原理:把原始数组分成若干子数组,对每一个子数组进行排序,继续把子数组与子数组合并,合并后仍然有序,直到全部合并完,形成有序的数组,因此空间复杂度为O(n)。

    归并操作的过程如下:

    1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
    2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
    3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
    4. 重复步骤3直到某一指针达到序列尾
    5. 将另一序列剩下的所有元素直接复制到合并序列尾

    理解:递归便是深度遍历(如下由左至右进行遍历),假设有这样的一列数组{9,8,7,6,5,4,3,2,1}进行划分的顺序如下:

    {9,8,7,6,5,4,3,2,1} --> {9,8,7,6,5},{4,3,2,1}

    {9,8,7,6,5} --> {9,8,7},{6,5}

                            {9,8,7} --> {9,8},{7}

                                              {9,8} --> {9},{8}

                            {6,5} -->{6},{5}

    {4,3,2,1} --> {4,3},{2,1}

                          {4,3} -->{4},{3}

                          {2,1} -->{2},{1}

    当深度划分到左右数组都只剩1个元素的时候,进行上述逆序的合并:

    {9},{8} --> {8,9} 然后和 {7} --> {7,8,9}

                                    {6},{5} --> {5,6}    然后 {7,8,9}和{5,6} --> {5,6,7,8,9}

                                         {2},{1} --> {1,2}

                                         {4},{3} --> {3,4}   然后 {1,2}和 {3,4} --> {1,2,3,4}

                              最终{5,6,7,8,9}和{1,2,3,4} --> {1,2,3,4,5,6,7,8,9}

    2.示例

            //归并排序
            public static int[] MergeSort(int[] nums)
            {
                if (nums.Length < 2)
                    return nums;
    
                int mid = nums.Length / 2;
                int[] left = new int[mid];
                int[] right = new int[nums.Length - mid];
    
                for (int i = 0; i < mid; i++)
                {
                    left[i] = nums[i];
                }
                for (int j = mid; j < nums.Length; j++)
                {
                    right[j - mid] = nums[j];
                }
    
                left = MergeSort(left);
                right = MergeSort(right);
    
                return merge(left, right);
            }
    
            private static int[] merge(int[] left, int[] right)
            {
                int[] temp = new int[left.Length + right.Length];
                int tempIndex = 0, lIndex = 0, rIndex = 0;
    
                while (lIndex < left.Length && rIndex < right.Length)
                {
                    if (left[lIndex] <= right[rIndex])
                    {
                        temp[tempIndex++] = left[lIndex++];
                    }
                    else
                    {
                        temp[tempIndex++] = right[rIndex++];
                    }
                }
                for (int i = lIndex; i < left.Length; i++)
                {
                    temp[tempIndex++] = left[i];
                }
                for (int i = rIndex; i < right.Length; i++)
                {
                    temp[tempIndex++] = right[i];
                }
    
                return temp;
            }
            //    int[] list = new[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
            //    var sort = Sorter.MergeSort(list);

    参考:http://www.cnblogs.com/mingmingruyuedlut/archive/2011/08/18/2144984.html

    作者:Qlin
    出处:http://www.cnblogs.com/qqlin/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    java基础---13. 匿名对象
    java基础---12. scanner
    java基础---11. API
    Web APIs---2. DOM(1)
    Web APIs---1.概述
    java基础---10. 封装性
    java基础---9. 面向对象
    java基础---8. 数组
    9月1日,随便写点啥
    银川行路随感
  • 原文地址:https://www.cnblogs.com/qqlin/p/2935132.html
Copyright © 2020-2023  润新知