zoukankan      html  css  js  c++  java
  • 基础排序算法之并归排序(Merge Sort)

    并归排序是学习分治法 (Merge Sort) 的好例子。而且它相对于选择,插入,冒泡排序来说,算法性能有一定提升。我首先会描述要解决的问题,并给出一个并归排序的例子。之后是算法的思路以及给出伪代码。算法的实现部分用Python完成。最后自己尝试说明白算法分析。

    问题描述

    问题描述很简单,输入一组未排序的数组,如左边的数组,通过并归排序算法的计算,输出一组正确排序的数组,如右边的数组。

    如果利用上面这个例子来做并归排序的话,应该首先将该数组切割成两半,对左边一半进行排序,在对右边一半进行排序,在合并排序好的左右数组。如下图所示:

    思路和伪代码

    可以从例子中看出,并归排序就是一个先分后合的过程:

    1. 递归排序左半部分数组;
    2. 递归排序右半部分数组;
    3. 合并 (Merge) 这两部分生成最后结果。 

    合并 (Merge)过程的核心思想就是:给左右两个数组分别设定一个标记符号i和j,通过比对当前i和j位置的数的大小,选择小的值加入到最后的结果中去。

    合并(Merge) 的伪代码:

     1 C = output[length=n]
     2 A = 1st sorted array[n/2]
     3 B = 2st sorted array[n/2]
     4 i = 1
     5 j = 1
     6 for k=1 to n
     7     if A(i) < B(j)
     8         C(k) = A(i)
     9         i++
    10     else B(j) < A(i)
    11         C(k) = B(j)
    12         j++
    13 end

    算法实现

     1 def merge(left, right):
     2     result = []
     3     i, j=0, 0
     4     ll, lr = len(left), len(right)
     5     while i < ll and j < lr:
     6         if i < ll and j < lr:
     7             if left[i] < right[j]:
     8                 result.append(left[i])
     9                 i = i+1
    10             else:
    11                 result.append(right[j])
    12                 j =j+1       
    13     result+=left[i:]
    14     result+=right[j:]
    15     return result
    16 
    17 
    18 def merge_sort(datalist):    
    19     length=len(datalist)
    20     result=datalist
    21     if length>1:        
    22         left=datalist[0:int(length/2)]
    23         right=datalist[int(length/2):length]       
    24         left=merge_sort(left)
    25         right=merge_sort(right)
    26         result=merge(left,right)
    27     return result
    View Code

    算法分析

    首先来分析在合并 (Merge) 过程的所需要的运行时间。

     1 C = output[length=n]
     2 A = 1st sorted array[n/2]
     3 B = 2st sorted array[n/2]
     4 i = 1
     5 j = 1
     6 for k=1 to n
     7     if A(i) < B(j)
     8         C(k) = A(i)
     9         i++
    10     else B(j) < A(i)
    11         C(k) = B(j)
    12         j++
    13 end

    第4和5行分别需要一次操作,整个for循环中,一次循环需要四次操作,假如有m个数那么for循环整个需要4m次操作,那么最后的运行时间为4m+2。因为m总是大于1,所以为了方便计算,假设最后运行时间小于6m。

    之后再来看整个算法的运行时间,采用递归树的方法,树的高度为lg­n+1,树的每一层运行时间都是6n,总共的运行时间为6nlgn+6n。所以合并排序的时间复杂度为O(nlgn)。

  • 相关阅读:
    【心情】codeforces涨分啦!
    redis
    rabbitmq
    lucene
    MongoDB
    负载均衡
    分布式存储
    Memcache
    websocket
    Remoting
  • 原文地址:https://www.cnblogs.com/cleverxy/p/3285540.html
Copyright © 2011-2022 走看看