归并排序法

归并排序(MergeSort)主要采用的思想是分治法,就是“分而治之,各个击破”,将复杂的问题拆减为多个简单的小问题,将小问题解决的结果再拼接为最终的结果。这种思想很好,也可以用在我们现实遇到的问题中。改算法的复杂度,该算法的复杂度也是 O(N*logN),需要 O(N)的空间,属于稳定排序

 
步骤:
Step1:将原问题分解为若干个规模较小,相互独立,且易解决的子问题
 
Step2:若子问题规模较小则直接解决,否则递归分解子问题,直到分解后的子问题统一解决为止
 
Step3:将子问题的解合并为原问题的解
 
伪代码:
MergeSort(a)
  if(Length(a)==1)
    return a[0];
  else
    //recursive calls
    [left_array,right_array]:=Split_Into_Equally_Size(a);
    left_array_new:=MergeSort(left_array);
    right_array_new:=MergeSort(right_array);
    //merge the 2 small order arrays into a big one
    return Merge(left_array_new,right_array_new);

 

C#代码:
        /// <summary>
        /// 归并排序(合并排序)
        /// </summary>
        /// <param name="list">需要排序的数组</param>
        /// <returns></returns>
        public static List<int> MergeSort(List<int> list)
        {
            if (list.Count == 1)
            {
                return list;
            }
            else
            {
                List<int> left_array = new List<int>();
                List<int> right_array = new List<int>();
                Split_Into_Equally_SizeList(list, ref left_array, ref right_array);
                List<int> left_array_new = MergeSort(left_array);
                List<int> right_array_new = MergeSort(right_array);

                List<int> result = new List<int>();
                Merge(left_array_new, right_array_new, ref result);
                return result;
            }
        }

        /// <summary>
        /// 合并排序
        /// </summary>
        /// <param name="listA">经过排序的数组A</param>
        /// <param name="listB">经过排序的数组B</param>
        /// <param name="result">排序后的数组</param>
        /// <returns></returns>
        private static void Merge(List<int> listA, List<int> listB,ref List<int>result)
        {
            if (listA.Count==0)
            {
                result.AddRange(listB);
                return;
            }else if (listB.Count==0)
            {
                result.AddRange(listA);
                return;
            }
            else
            {
                if (listA[0]<listB[0])
                {
                    result.Add(listA[0]);
                    listA.Remove(listA[0]);
                }
                else
                {
                    result.Add(listB[0]);
                    listB.Remove(listB[0]);
                }
            }
            Merge(listA, listB, ref result);
        }

        /// <summary>
        /// 将一个数组拆分为相等大小的2个
        /// </summary>
        /// <param name="list">原数组</param>
        /// <param name="left"></param>
        /// <param name="right"></param>
        private static void Split_Into_Equally_SizeList(List<int> list, ref List<int> left, ref List<int> right)
        {
            List<int> temp_left = new List<int>();
            List<int> temp_right = new List<int>();
            list.ForEach(delegate(int item)
            {
                if (list.IndexOf(item) % 2 == 0)
                {
                    temp_left.Add(item);
                }
                else
                {
                    temp_right.Add(item);
                }
            });
            left = temp_left;
            right = temp_right;
        }

 

 
 
 
 
 
 
 
 
 
 
posted @ 2019-05-02 19:22  NCat  阅读(155)  评论(0)    收藏  举报