归并排序

  归并排序说的简单一点就是把一个大的序列分成多个子序列,再别对各个子序列进行排序,等所有子序列都排序完成之后,再逐步从所有的子序列里面抽出最小的元素放回到大序列里面。直至所有元素都放回大序列,从而完成排序。

  是采用分治法的典型案例。

  本例是 二路归并。

 

归并排序  —— 递归实现  + 非递归实现

               一个大的序列

 

 

归并排序  —— 递归实现  + 非递归实现              分成两个子序列分别进行排序                                            归并排序  —— 递归实现  + 非递归实现

 

 

归并排序  —— 递归实现  + 非递归实现

  如图所示,最终将两个排好序的子序列,合并成一个,完成排序。

 

 

一种是递归的方式:

  该方法是递归的将序列分成两个部分,直至每个部分都只有一个元素,然后在返回,逐个的将相邻部分,排序、合并从而实现总的排序。

归并排序  —— 递归实现  + 非递归实现

 

 代码如下:

def merge(left, right):
    """合并左右两个子序列"""
    merged = []  # 设置一个空序列用以盛放每次从子序列中拿出的小的元素
    i, j = 0, 0  #初始化 i j 两个游标,分别跟踪 左右两个子序列的最小元素,因为左右两个序列已经从小到大排序好了,所以i j 均为 0
    left_len, right_len = len(left), len(right)
    while i < left_len and j < right_len:   # i j 作为左右子序列的游标,他们是不能超过两个子序列的长度的。一旦超过,说明该子序列遍历完成
        if left[i] <= right[j]:  #分别比较两个子序列中最小的那个。即 i j分别指向的那两个元素
            merged.append(left[i])  #小的加入到 临时序列,同时 游标向右移动
            i += 1
        else:
            merged.append(right[j])
            j += 1
    merged.extend(left[i:])  #当上个循环退出的时候,说明其中一个子序列已经遍历完成,于是将另一个子序列的剩余所有元素放入到临时序列中
    merged.extend(right[j:])  #此中情况是 i 坐在的左序列提前遍历完了,于是右子序列的从j开始的所有剩余元素都放到临时序列中
    return merged   #返回临时序列


def merge_sort(lst):
    if len(lst) <= 1:  #如果序列的长度为 1 了,那么就返回该序列
        return lst
    middle = len(lst) // 2
    left = merge_sort(lst[:middle])  #递归的对序列的左半部分进行分解
    right = merge_sort(lst[middle:])  #递归的对序列的右半部分进行分解
    return merge(left, right)  #合并左右两个子序列。

a = [1,4,7,3,5,89,64,32,46]
print(merge_sort(a))
View Code

相关文章:

  • 2021-05-03
  • 2022-02-06
  • 2022-02-04
  • 2021-07-15
  • 2021-12-11
  • 2022-02-07
  • 2022-01-05
猜你喜欢
  • 2021-07-30
  • 2022-12-23
  • 2022-12-23
  • 2021-02-05
  • 2021-07-14
  • 2022-12-23
  • 2021-12-29
相关资源
相似解决方案