Fighting-算法-插入排序

"""
插入排序思想:
    每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中,直到全部记录插入完成。
经典的插入排序:直接插入排序、折半插入排序、希尔排序

待排序表L[1...n]在某次排序过程中的某一时刻状态如下“
       有序序列L[1...i-1]    L[i]    无序序列L[i+1....n]
为了实现将元素L(i)插入到已有序的子序列L[1...i-1]中,需执行以下几个步骤:

1)、查找出L(i) 在L[1...i-1]中的插入位置k
2)、将L[k...i-1]的所有元素全部后移一个位置
3)、将L[i]复制到L[k]

为了实现对L[1...n]的排序,可以将L(2)~L(n)依次插入到前面已排好序的子序列中,初始假定L[1]是一个已排好序的子序列。

"""


def insert_sort(nums):
    size = len(nums)
    for i in range(1, size):
        # temp 变量指向尚未排好序的元素(从第二个开始)
        temp = nums[i]
        # j指向前一个元素的下标
        j = i - 1
        # temp与前一个元素比较,若temp较小则前一个元素后移,j自减,继续比较
        while j >= 0 and temp < nums[j]:
            nums[j+1] = nums[j]
            j = j - 1
        #   temp 所指向元素的最终位置
            nums[j+1] = temp
    return nums

"""
折半插入排序:当排序表为顺序存储的线性表时,可以采用折半插入排序方法:
    即先折半查找出元素的的待插入位置,然后在统一地移动待插入位置之后的所有元素。

"""


def insert_two_devide_sort(nums):
    size = len(nums)
    for i in range(1, size):
        # 将nums[i]暂存到temp
        temp = nums[i]
        # 设置折半查找的范围 先折半查找出元素的的待插入位置
        low = 0
        high = i - 1
        while low <= high:
            mid = (low + high)//2
            if nums[mid] > temp:
                high = mid - 1
            else:
                low = mid + 1
        #  然后在统一地移动待插入位置之后的所有元素
        j = i - 1
        while j >= high + 1:
            nums[j+1] = nums[j]
            j = j - 1
        nums[high+1] = temp
    return nums


"""
希尔排序(缩小增量排序算法):
    算法基本思想:先将待排序表分割成若干个形如L[i, i+d, i+2d, ...,i+kd]的‘特殊’子表。
    分别进行直接插入排序,当整个表中的元素已呈‘基本有序’时,再对全体记录进行一次直接插入排序。
    希尔排序的排序过程如下:
    
    先取一个小于n的步长d1,把表中的全部记录分成d1个组,所有记录为d1的倍数的记录放在同一个组中,在各个组中进行直接插入排序;
    然后取第二个步长d2<d1,重复上述过程,知道所取到的dt=1,即所有的记录已放在同一组中,再进行直接插入排序,由于此时已经具
    有较好的局部有序性,故可以很快的得到最终结果。
    
"""


def shell_sort(nums):
    """
    与直接插入排序相比:1、前后记录位置的增量是dk,不是1
    :param nums:
    :return:
    """
    size = len(nums)
    dk = size//2
    while dk >= 1:
        for k in range(dk):
            for i in range(k+dk, size, dk):
                temp = nums[i]
                j = i - dk
                while j >= k and temp < nums[j]:
                    nums[j+dk] = nums[j]
                    j = j - dk
                nums[j+dk] = temp
        dk = dk // 2
    return nums


if __name__ == '__main__':
    lists = [3, 5, 1, 2, 4]
    print(lists)
    print(insert_sort(lists))
    print(insert_two_devide_sort(lists))
    print(shell_sort(lists))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值