归并排序(Python)

一.采用分治策略:将原问题划分成n个规模较小的但结构和原问题相同的子问题,递归解决这些子问题后合并各个结果从而得到原问题的解。

 

二.分治策略的步骤:

  • 分解:将原问题分解成一系列子问题
  • 解决:子问题粒度足够小、能直接求解则直接求解,子问题不能直接求解则继续递归分解为更小的子问题
  • 合并:将子问题的结果合并为原问题的解

   总的来说就是递归分解问题至能直接求解,然再将各子问题的结果合并在一起从而得到原问题的解

 

三.归并排序(以整数排序为例)

  3.1将待排序的数组为左右两个组单独排序,然后合并左右两个已排序好的数组,不断递归这个过程知道数组大小为1

 

  3.2伪代码

    merge_sort(A, start, end)  //A为待排序数组, start和end分别为需要排序的部分的开始和结束的元素下标

      if start < end      //问题不能直接求解,需要分解

        m = (start + end) / 2     //找出中间位置

        merge_sort(start, m)  //对左半部分排序

        merge_sort(m+1, end)  //对右半部分排序

        merge(A, start, m, end) //合并左右两部分

 

  3.3merge(A, start, m, end)函数

   A为数组, start、m和end为开始、中间和结束下标

   merge(A, start, m, end)

    left_size = m - start

    right_size = end - m + 1

    L[left_size] = {0}

    R[right_size] = {0}

    for i = 0 to (left_size -1)

      L[i] = A[start+i]

    for j = 0 to (right_size -1)

      R[j] = A[m + j]

 

    i = 0

    j = 0

    for n = start to end

      if L[i] <= R[j]

        A[n] = L[i]

        ++i

      else

        A[n] = R[j]

        ++j

 

四.Python代码

import sys

def merge(A, start, middle, end):
    arr_left = A[start : middle + 1]
    arr_right = A[middle + 1 : end + 1]

    i = 0;
    j = 0;

    left_len  = len(arr_left)
    right_len = len(arr_right)

    for n in range(start, end + 1):
        if arr_left[i] <= arr_right[j]:
            A[n] = arr_left[i]
            i = i + 1
            if i >= left_len:    #左边的已经比较完,直接将剩下的右边赋值给A
                A[n+1 : n + right_len - j + 1] = arr_right[j : ]
                return None
        else:
            A[n] = arr_right[j]
            j = j + 1
            if j >= right_len:   #右边的已经比较完,直接将剩下的左边赋值给A
                A[n+1 : n + left_len - i + 1] = arr_left[i : ]
                return None

def merge_sort(A, start, end):
    if start < end:
        middle = (end + start) / 2

        merge_sort(A, start, middle)
        merge_sort(A, middle + 1, end)
        merge(A, start, middle, end)


def main(argv=None):
    A = [9, 3, 10, 34, 25, 11, 100, 29, 64, 82, 55, 43, 73]

    print "before : ", A

    merge_sort(A, 0, len(A) - 1)

    print "after : ", A



if __name__ == "__main__":
    sys.exit(main())

 

运行结果:

posted @ 2016-06-17 22:33  KbDaVinci  阅读(309)  评论(0编辑  收藏  举报