归并排序 python3

p2_1归并排序O(nlogn)
题目:
给定你一个长度为 n 的整数数列。

请你使用归并排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

输入格式
输入共两行,第一行包含整数 n。

第二行包含 n 个整数(所有整数均在 1∼109 范围内),表示整个数列。

输出格式
输出共一行,包含 n 个整数,表示排好序的数列。

数据范围
1≤n≤100000
输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5

#Python使用缩进对齐组织代码的执行,所有没有缩进的代码(非函数定义和类定义),
# 都会在载入时自动执行,这些代码,可以认为是Python的main函数。

#2路归并:把两个已经有序的序列合并成一个,可以把一列数的每一个数字看成是一个独立是子序列,直接合并就行
#但是因为输入的序列所以先得把他们一一分割成独立的数字,所以归并函数先分割!
#每次合并都是相邻的序列!!!!(因为mid一分为二啊!!!!想象一下)
#见百度云第八章9-12min


#快排是先分左右,再递归;归并是先递归再合二为一
#快排不稳定,归并稳定:当两个对比数相等时候,取第一个数,第一个指针后移---为了稳定

#快排是【从长到短】,归并是【从短到长】

#时间复杂度为O(nlogn):因为整个序列长n,递归的第二层为:两个n/2的,,第三层为4个n/4, 。。。,n个长度为1的序列
#所以一共递归logn次,每次复杂度为n  【n = 2^x,解得x = log 2 n(2为底数)】

#对每个序列从中间一分为二,再对比合并
#选数mid=(l+r)/2
#递归排序
#将有序的列合二为一


def merge_sort(nums,l,r):#每次这个lr都直接想成某一个序列的左右端点,而不只是初始的lr
    if l>=r: return
    mid=(l+r)//2
    merge_sort(nums,l,mid)#感受这句话!!!:对左边递归的排序使得有序!!递归到头就是一个独立的数字,再相邻两个归并
    merge_sort(nums,mid+1,r)
    i = l
    j = mid + 1
    k=0
    while i<=mid and j<=r:
        if nums[i]<=nums[j]:
            tmp[k]=nums[i]
            k+=1
            i+=1
        else:
            tmp[k]=nums[j]
            k+=1
            j+=1   #大的while循环结束必有i=mid+1且j<=r   或者j=r+1且i<=mid
    while i<=mid:#都扫尾肯定没错
        tmp[k]=nums[i]
        k+=1
        i+=1
    while j<=r:#都扫尾肯定没错
        tmp[k]=nums[j]
        k+=1
        j+=1

    # 将排序好的tmp数组存到nums对应部分中, 因为这个已经在函数里面,所以要注意不能直接等!
    i = l
    k = 0#每个循环里面生成的tmp都是从k=0开始的,充当的是nums里面从l开始的到r结束的
    while i <= r:
        nums[i] = tmp[k]
        i += 1
        k += 1



if __name__=="__main__":#这个和main()不一样,这里面定义的变量可用于其他函数中,main则不行不,而且个如果这个要调用某个函数则只能放在该函数后
    length=int(input("n\n").strip())
    nums = list(map(int,input("nums\n").split()))
    tmp = [0] * length# 一维数组可以这么生成,二维数组不行
    merge_sort(nums,0,length-1)
    print(' '.join(map(str, nums)))#nums不需要再split
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值