归并排序(MergeSort)

//版权所有
Anders06  于2007年10月25日

归并排序(Merge Sort)是利用”归并”技术来进行排序。归并是指将若干个已排序的子文件合并成一个有序的文件。
1、基本思想
1 分治法的基本思想
分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。

2 归并排序的基本基本步骤
  设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。

  •   分解: 讲n个元素分成n/2 个元素的子序列
  •   解决: 用合并并排序对两个子序列递归地排序    (在对子序列排序时,长度为1时递归结束)
  •   合并: 合并两个已经排好序的子列序以得到排序结果  

    以扑克牌为例, 假设有两堆牌面朝上地放在桌上,每一堆都是排好序的,最小的牌在最上面。我们希望将两堆牌合并成升序的一堆牌。基本步骤包括在面朝上的两堆牌中,选择顶上两张较小的一张,将其取出放入到输出堆,重复此动作,知道有一堆为空为止,然后吧另一堆所剩下的牌面朝下放入到输出堆即可。 合并排序的时间为 O(n).

2、 算法分析
1)时间复杂度
    Merge过程运行的时间为O(n), 而我们总共分了lgn + 1(n为偶数的时候应该为lgn吧, 数学好久没读,头脑不好用咯),因此总的执行实际为nlgn + n,复杂度为 O(nlgn)
2)空间复杂度
    O(n)
3)稳定性
    为稳定算法

C#实现的MergeSort

《归并排序(MergeSort)》
《归并排序(MergeSort)》
MergeSort

public class MergeSort<T> where T : IComparable
{
    
/// <summary>
    
/// Sort Array
    
/// </summary>
    
/// <param name=”sortArray”></param>
    public static void Sort(T[] sortArray)
    {
        Sort(sortArray, 
0, sortArray.Length  1);
    }

    /// <summary>
    
/// Recursion Sort array from startIndex to endIndex
    
/// Divide the range of array to two part, sort of them and finally merge them as one
    
/// </summary>
    
/// <param name=”sortArray”>The array need to be sort</param>
    
/// <param name=”startIndex”>Start index of sortArray</param>
    
/// <param name=”endIndex”>End index of sortArray</param>
    private static void Sort(T[] sortArray, int startIndex, int endIndex)
    {
        Debug.Assert(startIndex 
<= endIndex);

        if (startIndex < endIndex)        // more then one element
        {
            
int mid = (startIndex + endIndex) / 2;
            Sort(sortArray, startIndex, mid);
            Sort(sortArray, mid 
+ 1, endIndex);
            Merge(sortArray, startIndex, mid, endIndex);
        }
    }

    /// <summary>
    
/// Merge two arrays as one, make it still sorted
    
/// Make sure sortArray[startIndex《归并排序(MergeSort)》midIndex]; sortArray[midIndex+1《归并排序(MergeSort)》endIndex] have been sorted
    
/// </summary>
    
/// <param name=”sortArray”>The whole array need to be sorted</param>
    
/// <param name=”startIndex”>The first index of the first part</param>
    
/// <param name=”midIndex”>The end index of first part<param>
    
/// <param name=”endIndex”>The end index of second part</param>
    private static void Merge(T[] sortArray, int startIndex, int midIndex, int endIndex)
    {
        Debug.Assert(startIndex 
<= midIndex);
        Debug.Assert(midIndex 
< endIndex);

        int firArrayLength = midIndex  startIndex + 1;
        
int secArrayLength = endIndex  midIndex;

        T[] fisArray = new T[firArrayLength];
        T[] secArray 
= new T[secArrayLength];
        Array.Copy(sortArray, startIndex, fisArray, 
0, firArrayLength);
        Array.Copy(sortArray, midIndex 
+ 1, secArray, 0, secArrayLength);

        int i = 0;
        
int j = 0;
        
for (int index = startIndex; index <= endIndex ; index++)
        {
            
if (i >= firArrayLength)
            {
                
for(; j< secArrayLength; j++)
                    sortArray[startIndex 
+ i  + j ] = secArray[j];

                break;
            }
            
if (j >= secArrayLength)
            {
                
for (; i < firArrayLength; i++)
                    sortArray[startIndex 
+ i  + j] = fisArray[i];

                break;
            }

            if (fisArray[i].CompareTo(secArray[j]) <= 0)
            {
                sortArray[startIndex 
+ i + j] = fisArray[i];
                i
++;
            }
            
else
            {
                sortArray[startIndex 
+ i + j] = secArray[j];
                j
++;
            }
        }
    }
}

参考资料

  •     <<算法导论>>
    原文作者:Anders06
    原文地址: https://www.cnblogs.com/anders06/archive/2007/10/25/937560.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞