排序算法-冒泡/插入/归并/希尔排序(python实现)

排序算法-冒泡/插入/归并/希尔排序(python实现)

注意:实现的代码均为对序列的非递减排序操作

1. 冒泡排序

参考博客: https://blog.csdn.net/guoweimelon/article/details/50902597
核心思想:
(1)遍历N趟排序,每次获取序列中最大或者最小的元素,移动到序列的末端位置
(2)每一趟排序过程都两两比较相邻的元素,将较大/小的元素放置到后一个位置
(3)时间复杂度O(n^2), 空间复杂度O(1)

python实现:

# 冒泡排序
def bubble_sort(input_arr):
    input_length = len(input_arr)
    for i in range(0, input_length):
        for j in range(0, input_length - i - 1):
            if input_arr[j] > input_arr[j+1]:
                input_arr[j], input_arr[j+1] = input_arr[j+1], input_arr[j]

    return input_arr
2. 插入排序

参考博客: https://blog.csdn.net/guoweimelon/article/details/50904201
核心思想:
(1)遍历N趟排序,每一趟排序过程都将未排序的序列插入到已经排序序列的适当位置
(2)时间复杂度O(n^2), 空间复杂度O(1)

python实现:

# 插入排序
def insert_sort(input_arr):
    input_length = len(input_arr)
    for i in range(1, input_length):
        temp = input_arr[i]
        # 此处遍历为查找合适的位置进行插入操作
        for j in range(i-1, -1, -1):
            if input_arr[j] > temp:
                input_arr[j + 1] = input_arr[j]
            else:
                input_arr[j + 1] = temp
                break
    return input_arr
3. 折半插入排序

参考博客:https://blog.csdn.net/guoweimelon/article/details/50904206
核心思想:
(1)遍历N趟排序, 每一趟排序过程都将未排序的序列插入到已经排序序列的适当位置
(2)上述普通插入排序过程中,每次查找适当位置的时候都是直接遍历的,可以尝试使用折半查找的方法进行查找适当的插入位置
(3)时间复杂度O(n^2), 空间复杂度O(1)

python实现:

def binary_insert_sort(input_arr):
    input_length = len(input_arr)
    for i in range(1, input_length):
        temp = input_arr[i]

        # 使用二分查找的方法,查找[0, i]之间可以插入元素temp的位置
        left = 0
        right = i
        while left < right:
            mid = left + int((right - left) / 2)
            if input_arr[mid] >= temp:
                right = mid
            else:
                left = mid + 1
        # 查找到合适的位置之后执行插入
        for j in range(left, i):
            input_arr[j+1] = input_arr[j]
        input_arr[left] = temp

    return input_arr
4. 归并排序

核心思想:
(1)将待排序序列分成若干子序列,对子序列递归进行归并排序,再将子序列合并成整体有序序列
(2)时间复杂度O(nlogn),空间复杂度O(n)。

归并排序可以自顶向下排序,也可以进行自底向上排序.
自顶向下:从需要归并序列的全部序列出发,依次进行分割:
如对[1,4,5,7,2,6]分割顺序为: (1) [1,4,5],[7,2,6]; (2) [1,4],[5];[7,2],[6]
自底向上:从归并序列的底部出发,即从序列的每一个独立的子序列出发,依次向上归并,如(1) [1,4],[5,7],[2,6]; (2)[1,4,5,7],[2,6]; (3) [1,2, 4,5,6, 7]
https://www.cnblogs.com/agui521/p/6918229.html
自底向上的归并排序对索引值进行操作,故能够很好的对链表数据进行排序.

python实现(自顶向下的归并排序)

# 合并两个有序列表
def merge_list(arr_1, arr_2):

    left, right = 0, 0
    len_1, len_2 = len(arr_1), len(arr_2)
    res = []
    # 当第一个有序列表和第二个有序列表都没有遍历结束的时候
    while left < len_1 and right < len_2:
        if arr_1[left] <= arr_2[right]:
            res.append(arr_1[left])
            left += 1
        else:
            res.append(arr_2[right])
            right += 1

    # 当存在某个列表被遍历结束,则直接将另一个列表的元素插入结果
    while left < len_1:
        res.append(arr_1[left])
        left += 1

    while right < len_2:
        res.append(arr_2[right])
        right += 1

    return res

def merge_sort(input_arr):
    if len(input_arr) <= 1:
        return input_arr

    # 拆分列表
    mid = int(len(input_arr) / 2)
    left = merge_sort(input_arr[0: mid])
    right = merge_sort(input_arr[mid:])
    return merge_list(left, right)
5. 希尔排序

参考博客: https://blog.csdn.net/guoweimelon/article/details/50904214
核心思想:
(1) 希尔排序: 对原始序列进行分组排序,插入排序对几乎有序的序列排序时间呈线性的
(2) 核心思想: 先将待排序的序列分割成若干子序列进行插入排序,待整个序列基本有序,再进行整体插入排序;首先要选择一个增量序列d = {n/2 ,n/4, n/8 …1}

python实现:

# 对每个组内的元素进行排序
def gap_sort(arr, start_index, gap_length):
    for i in range(start_index + gap_length, len(arr), gap_length):
        temp = arr[i]
        for j in range(i-gap_length, -1, -gap_length):
            if arr[j] > temp:
                arr[j + gap_length], arr[j] = arr[j], arr[j + gap_length]
            else:
                arr[j + gap_length] = temp
                break
    return arr


def shell_sort(input_arr):
    input_length = len(input_arr)

    step = 2
    # gap表示一个分组内元素的间隔
    gap = input_length // step

    while gap > 0:
        # 对每一组进行排序
        for i in range(0, gap):
            input_arr = gap_sort(input_arr, i, gap)
        # 排序后重新分组
        gap = gap // step

    return input_arr
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值