排序五 归并排序

归并排序(Merge Sort)

归并排序(Merge-Sort)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。—百度百科

  • 时间复杂度:最好 O(n)=O(nlogn);平均O(n)=O(nlogn);最差O(n)=O(nlogn)
  • 空间复杂度:O(n)=O(n)
  • 稳定性:    稳定

算法描述

写作功底有限,不明白的推荐看一下麻省理工学院的算法导论公开课

归并(Merge)

归并算法是指将两个有序序列合并为一个有序序列的方法。

例如,现有两个有序序列A[1,3,5], B[2,4,6],将其合并为一个序列C。
分别对A,B建一个游标索引,初始值为0。
第一步比较A,B索引的值A[1,3,5],B[2,4,6],1 < 2,所以C=[1,…],      A的索引+1。
第二步比较A,B索引的值A[1,3,5],B[2,4,6],3 > 2,所以C=[1,2,…],     B的索引+1。
第三步比较A,B索引的值A[1,3,5],B[2,4,6],3 < 4,所以C=[1,2,3,…],   A的索引+1。
第四步比较A,B索引的值A[1,3,5],B[2,4,6],5 > 4,所以C=[1,2,3,4…],  B的索引+1。
第五步比较A,B索引的值A[1,3,5],B[2,4,6],5 < 6,所以C=[1,2,3,4,5…],A的索引+1。
此时A中元素已全部取完,后续只需将B中元素按次序放入C即得C[1,2,3,4,5,6]

归并排序(Merge Sort)

  1. 分解:将序列分为两组A,B,再对A,B各自分成两组。依次类推,当每组中只有一个元素时,可认为每个小组都是有序的。
  2. 归并:将步骤1中分成的小组,递归的进行两两归并,直到归并为一个数组。
    Merge Sort
    图片来自维基百科

排序示例

Merge Sort

示例代码

public static void MergeSort(int[] S){  //C#
    MergeSort(S, 0, S.Length - 1);
}
private static void MergeSort(int[] S, int first, int last){
    if (first < last){
        int mid = (first + last) / 2;
        MergeSort(S, first, mid);   //分解
        MergeSort(S, mid + 1, last);//分解
        Merge(S, first, mid, last); //归并
    }
}
/// <summary>
/// 归并,将两个有序序列合并为一个有序序列
/// </summary>
private static void Merge(int[] S, int first, int mid, int last){
    int[] temp = new int[last - first + 1];
    int i = first;
    int j = mid + 1;
    int k = 0;
    while (i <= mid && j <= last){
        if (S[i] <= S[j]){
            temp[k++] = S[i++];
        } else {
            temp[k++] = S[j++];
        }
    }
    while (i <= mid){
        temp[k++] = S[i++];
    }
    while (j <= last){
        temp[k++] = S[j++];
    }
    Array.Copy(temp, 0, S, first, temp.Length);
}
def merge_sort(s):  #Python
    if len(s) <= 1:
        return s
    mid = len(s) // 2
    left = merge_sort(s[:mid])
    right = merge_sort(s[mid:])
    #注意:并非原地排序,是新建了一个列表并返回
    return merge(left, right)

def merge(left, right):
    result = []
    i = 0
    j = 0
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1

    result += left[i:]
    result += right[j:]
    return result

文中若有什么错误,欢迎留言指正。

转载请保留出处:http://blog.csdn.net/x1060549/article/details/78781643

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值