归并排序

归并排序分分解和归并两个步骤。分解就是将一组数一级级分解到单个数,归并就是将一组左右都是有序但是合起来无序的数排序。

一、先说归并
在这里插入图片描述
上图是一组左右两边都有序,但是合起来无序的数组,对这样的数组进行排序就叫归并。
1、首先确定两个位置标示,即为两个箭头,第一个为low,第二个为high,在排序开始前分别指向左右有序数组的第一个位置,还有一个中间位置mid,这里定义为‘9’的位置。归并函数需要输入(list,low,mid,high)几个参数,list为数组
2、然后分别比较low和high指向位置的数的大小,可以看到high指向的位置为1比2小,将1存放到另一个新建数组的第一个位置,high向右移动加1。
3、重复2的步骤,直到high大于数组长度或者low大于mid
4、当3满足条件时,将剩下的数直接拷贝到新建数组的末端

def merge(list,low,mid,high):
    p1 = low
    p2 = mid + 1
    li = []
    while(p1<=mid and p2<=high):
        if(list[p1]<list[p2]):
            li.append(list[p1])
            p1 = p1 + 1
        else:
            li.append(list[p2])
            p2 = p2 + 1
    
    while(p1 <= mid):
        li.append(list[p1])
        p1 = p1 + 1
    while(p2 <= high):
        li.append(list[p2])
        p2 = p2 + 1
    
    list[low:high+1] = li

二、 分解
上面归并是对左右两边有序的数组进行排序,但是我们要排序的数组并不是两边有序的数组。所以我们需要将其进行分解,如图所示,将数组一级级分解,当分解到只有一个数时就是左右有序的了,因为一个数本身就是有序的。然后我们只需调用上面写的归并函数进行一级级往回归并就可以得到一组有序的数组。
在这里插入图片描述

def merge_sort(list,low,high):
    if(low < high):
        mid = (low + high)//2
        merge_sort(list,low,mid)
        merge_sort(list,mid+1,high)
        merge(list,low,mid,high)

下面是整体代码

def merge(list,low,mid,high):
    p1 = low
    p2 = mid + 1
    li = []
    while(p1<=mid and p2<=high):
        if(list[p1]<list[p2]):
            li.append(list[p1])
            p1 = p1 + 1
        else:
            li.append(list[p2])
            p2 = p2 + 1
    
    while(p1 <= mid):
        li.append(list[p1])
        p1 = p1 + 1
    while(p2 <= high):
        li.append(list[p2])
        p2 = p2 + 1
    
    list[low:high+1] = li
                   


def merge_sort(list,low,high):
    if(low < high):
        mid = (low + high)//2
        merge_sort(list,low,mid)
        merge_sort(list,mid+1,high)
        merge(list,low,mid,high)
    

list = [i for i in range(10)]
import random
random.shuffle(list)  
print(list)

merge_sort(list,0,9)
print(list)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值