分治(二)合并排序、快速排序

三、合并排序——T(n)=Onlog2n
1.算法思想
合并排序是用分治策略对n个元素进行排序的算法。基本思想是递归地将待排序元素分成大小相同的两个子序列(直到分到最小)。分别对这两个子序列进行排序(自底向上),然后将两个子序列合并到一起。如下图:先将序列递归拆分到不能再分;然后在逐层排序
 
 
*2.算法实现
def MergeSort(lis): 
    if len(lis) == 1:    # 已经不能再继续二分了
        return lis
    mid = len(lis) // 2
    l = MergeSort(lis[:mid])    # 将序列递归地二分,并对子序列进行排序
    r = MergeSort(lis[mid:])    # l 和 r 的规模是从小到大的,从小规模就开始排序直到两个最大的子序列
    res = []    # 结果集
    i, j = 0, 0
    while i < len(l) and j < len(r):    # 对两个子序列的元素进行比较,较小的放入结果集,直至有个子序列放完
        if l[i] <= r[j]:
            res.append(l[i])
            i += 1
        else:
            res.append(r[j])
            j += 1
    # 将 l 或 r 中剩余的放入res
    if i < len(l):
        res += l[i:]
    if j < len(r):
        res += r[j:]
    # 这里有个疑问:为什么在最后一次归并之前不会return出去?
    return res
 
 
 
 
四、快速排序
 
1.该方法的基本思想是(T(n)=O(n*log2n))
-先从数列中取出一个数作为基准数
-分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边
-再对左右区间重复第二步,直到各区间只有一个数
 
*2.算法实现
def QuickSort(lis, l, r):
    if l >= r:  # 若 l 或 r 超出下标范围,直接return
        return
    i, j =l, r
    base = lis[i]   # 取一个基准点
    while i < j:
        while i < j and lis[j] > base:  # 先从后向前找较小的数
            j -= 1
        while i < j and lis[i] <= base: # 从前向后找较大的,找到后不再循环
            i += 1
        if i < j:   # 如果i在j之前,那么交换 i 和 j
            lis[i], lis[j] = lis[j], lis[i]
    lis[l], lis[j] = lis[j], base   # 当 i 和 j 相同的时候,把 基准点 和 j (/i)交换
    QuickSort(lis, l, j - 1)    # 递归地将基准点前后两个部分进行快排
    QuickSort(lis, j + 1, r)
    return lis

猜你喜欢

转载自www.cnblogs.com/xiaoqichaoren/p/12951646.html
今日推荐