十大经典排序算法——希尔排序、归并排序

希尔排序

算法步骤

  • 将一个数组根据步长分成k个序列,放在一个表中
  • 对列分别进行插入排序
  • 重复这过程,不断减少步长,直到最后整个表只有一列

举个?

数组[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ]

  • 以步长5进行分割,得到:
13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10
  • 对列进行插入排序
10 14 73 25 23
13 27 94 33 39
25 59 94 65 82
45

得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ]

  • 以3为步长进行分割,得到:
10 14 73
25 23 13
27 94 33
39 25 59
94 65 82
45

对列进行插入排序:

10 14 13
25 23 33
27 25 59
39 65 73
45 94 82
94
  • 最后以1步长进行插入排序

代码实现

def shell_sort(alist):
    n = len(alist)
    # 初始步长
    gap = n // 2
    while gap > 0:
        # 按步长进行插入排序
        for i in range(gap, n):
            j = i
            # 插入排序
            while j>=gap and alist[j-gap] > alist[j]:
                alist[j-gap], alist[j] = alist[j], alist[j-gap]
                j -= gap
        # 得到新的步长
        gap = gap // 2

测试

alist = [54,26,93,17,77,31,44,55,20]
shell_sort(alist)
print(alist)
[17, 20, 26, 31, 44, 54, 55, 77, 93]

归并排序

算法步骤

  • 申请空间,使其大小为两个已经排序序列之和
  • 设定两个指针,最初位置分别为两个已经排序序列的起始位置
  • 先递归分解数组,将列表越分越小,直至分成一个元素(这一个元素是有序的)
  • 比较两个数组的最前面的数,取小的元素到之前申请的空间,取了后相应的指针就往后移一位,最后列表越来越大

图片详解
在这里插入图片描述

代码实现

import math
def MergeSort(arr):
    if len(arr) < 2:
        return arr
    # 二分分解数组
    num = math.floor(len(arr)/2)
    left = MergeSort(arr[:num])
    right = MergeSort(arr[num:])
    # 合并
    return Merge(left,right)

def Merge(left,right):
    # 将两个有序数组left[],right[]合并成一个大的有序数组
    l , r = 0 ,0 # left与right的下表指针
    result= []
    while l <len(left) and r < len(right):
        if left[l] < right[r]:
            result.append(left[l])
            l += 1
        else:
            result.append(right[r])
            r += 1
    result += left[l:]
    result += right[r:]
    
    return result
            
            
            
            

测试

arr  = [54,26,93,17,77,31,44,55,20] 
sorted_arr = MergeSort(arr)
print(sorted_arr)
[17, 20, 26, 31, 44, 54, 55, 77, 93]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值