python排序算法(二) 插入、希尔、快速、归并

本文深入讲解了四种排序算法:插入排序、希尔排序、快速排序和归并排序。详细介绍了每种算法的工作原理、代码实现及时间复杂度,并讨论了它们的稳定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

插入排序(lnsertion Sort)

插入排序是⼀种简单直观的排序算法。它的⼯作原
理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插⼊。插⼊排序在实现上,在从后向前扫描过程中,需要反
复把已排序元素逐步向后挪位,为最新元素提供插⼊空间。

代码实现:

def insert_sort(alist):
    """插入排序"""
    for j in range(1, len(alist)):
        for i in range(j, 0, -1):
            if alist[i] < alist[i - 1]:
                alist[i - 1], alist[i] = alist[i], alist[i - 1]
            else:
                break


if __name__ == '__main__':
    list1 = [8, 4, 6, 5, 7, 9, 2, 3, 1]
    insert_sort(list1)
    print(list1)

时间复杂度

  • 最优时间复杂度:O(n) (升序排列,序列已经处于升序状态)
  • 最坏时间复杂度:O(n²)
  • 稳定性:稳定

希尔排序(shell sort)

希尔排序是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是⾮稳定排序算法。该⽅法因 DL.Shell于1959年提出⽽得名。希尔排序是把记录按下标的⼀定增量分
组,对每组使⽤直接插⼊排序算法排序;随着增量逐渐减少,每组包含的关 键词越来越多,当增量减⾄1时,整个⽂件恰被分成⼀组,算法便终⽌。

希尔排序过程

希尔排序的基本思想是:将数组列在⼀个表中并对列分别进⾏插⼊排序,重复这过程,不过每次⽤更⻓的列(步⻓更⻓了,列数更少了)来进⾏。最后整个表就只有⼀列了。将数组转换⾄表是为了更好地理解这算法,算法本身 还是使⽤数组进⾏排序。

代码实现:

def shell_sort(alist):
    """希尔排序"""
    n = len(alist)
    gap = n // 2
    while gap >= 1:
        for j in range(gap, n):
            i = j
            while (i - gap) >= 0:
                if alist[i] < alist[i - gap]:
                    alist[i], alist[i - gap] = alist[i - gap], alist[i]
                else:
                    break
        gap //= 2


if __name__ == '__main__':
    list1 = [5, 7, 6, 8, 2, 9, 1, 3, 4]
    shell_sort(list1)
    print(list1)


时间复杂度

  • 最优时间复杂度:根据步⻓序列的不同⽽不同
  • 最坏时间复杂度:O(n )
  • 稳定性:不稳定

快速排序(Quicksort)

快速排序(英语:Quicksort),⼜称划分交换排序(partition-exchange
sort),通过⼀趟排序将要排序的数据分割成独⽴的两部分,其中⼀部分的 所有数据都⽐另外⼀部分的所有数据都要⼩,然后再按此⽅法对这两部分数
据分别进⾏快速排序,整个排序过程可以递归进⾏,以此达到整个数据变成 有序序列。

代码实现:

def quick_sort(alist, start, end):
    """快速排序"""
    if start >= end:
        return

    mid = alist[start]
    left = start
    right = end

    while left < right:
        while left < right and alist[right] >= mid:
            right -= 1
        alist[left] = alist[right]
        while left < right and alist[left] < mid:
            left += 1
        alist[right] = alist[left]

    alist[left] = mid

    quick_sort(alist, start, left-1)
    quick_sort(alist, left+1, end)


if __name__ == '__main__':
    list1 = [5, 7, 6, 8, 2, 9, 1, 3, 4]
    quick_sort(list1, 0, len(list1)-1)
    print(list1)


时间复杂度

  • 最优时间复杂度:O(nlogn)
  • 最坏时间复杂度:O(n²)
  • 稳定性:不稳定

归并排序

归并排序是采⽤分治法的⼀个⾮常典型的应⽤。归并排序的思想就是先递归 分解数组,再合并数组。
将数组分解最⼩之后,然后合并两个有序数组,基本思路是⽐较两个数组的 最前⾯的数,谁⼩就先取谁,取了后相应的指针就往后移⼀位。然后再⽐
较,直⾄⼀个数组为空,最后把另⼀个数组的剩余部分复制过来即可。

代码实现

def merge_sore(alist):
    """归并排序"""
    n = len(alist)
    if 1 == n:
        return alist

    mid = n // 2
    # 对左半部分进行归并排序
    left_sorted_li = merge_sore(alist[:mid])
    # 对右半部分进行归并排序
    right_sorted_li = merge_sore(alist[mid:])
    # 合并两个有序集合
    left, right = 0, 0
    merge_sorted_li = []

    left_n = len(left_sorted_li)
    right_n = len(right_sorted_li)

    while left < left_n and right < right_n:
        if left_sorted_li[left] <= right_sorted_li[right]:
            merge_sorted_li.append(left_sorted_li[left])
            left += 1
        else:
            merge_sorted_li.append(right_sorted_li[right])
            right += 1

    merge_sorted_li += left_sorted_li[left:]
    merge_sorted_li += right_sorted_li[right:]

    return merge_sorted_li


if __name__ == '__main__':
    list1 = [5, 7, 6, 8, 2, 9, 1, 3, 4]
    a = merge_sore(list1)
    print(a)


时间复杂度

  • 最优时间复杂度:O(nlogn)
  • 最坏时间复杂度:O(nlogn)
  • 稳定性:稳定

exit(?)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值