当前位置: 首页 > article >正文

Python算法L2:排序算法(详细版)

目录

        • 前言
        • 1. 冒泡排序 (Bubble Sort)
        • 2. 选择排序 (Selection Sort)
        • 3. 插入排序 (Insertion Sort)
        • 4. 快速排序 (Quick Sort)
        • 5. 归并排序 (Merge Sort)
        • 6. 堆排序 (Heap Sort)
        • Python内置的`sorted()`函数
      • 总结

前言

排序算法是计算机科学中一个非常基本但又极为重要的主题。无论是数据分析、搜索算法,还是日常编程任务中,排序操作都频繁出现。Python 作为一个高级编程语言,内置了强大的排序功能,同时也允许开发者根据需求自定义排序算法。在这篇博客中,我们将介绍几种常见的排序算法,并展示如何在 Python 中实现它们。

1. 冒泡排序 (Bubble Sort)

冒泡排序是一种简单的交换排序算法。它的基本思想是反复比较相邻的元素,如果前一个元素大于后一个元素,就交换它们的位置,直到整个序列有序为止。

代码示例:

def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
    return arr

时间复杂度:

  • 最优时间复杂度:O(n) (当列表已经有序)
  • 平均时间复杂度:O(n²)
  • 最差时间复杂度:O(n²)

冒泡排序虽然简单,但效率较低,特别是对于大规模数据集。

2. 选择排序 (Selection Sort)

选择排序每次从未排序的部分选择最小的元素,将其放到已排序部分的末尾。它是一种不稳定的排序算法。

代码示例:

def selection_sort(arr):
    n = len(arr)
    for i in range(n):
        min_idx = i
        for j in range(i+1, n):
            if arr[j] < arr[min_idx]:
                min_idx = j
        arr[i], arr[min_idx] = arr[min_idx], arr[i]
    return arr

时间复杂度:

  • 最优时间复杂度:O(n²)
  • 平均时间复杂度:O(n²)
  • 最差时间复杂度:O(n²)

选择排序通常比冒泡排序更高效,因其交换次数较少。

3. 插入排序 (Insertion Sort)

插入排序通过逐一将元素插入到有序部分来构建最终的排序列表。它的工作方式类似于扑克牌的排序过程,逐个将每张牌插入到正确的位置。

代码示例:

def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i - 1
        while j >= 0 and key < arr[j]:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key
    return arr

时间复杂度:

  • 最优时间复杂度:O(n) (当列表已经有序)
  • 平均时间复杂度:O(n²)
  • 最差时间复杂度:O(n²)

插入排序对于小型数据集非常有效,并且在数据几乎有序的情况下表现优异。

4. 快速排序 (Quick Sort)

快速排序是一种基于分治法的高效排序算法。它通过选择一个基准点(pivot),将数组分为两部分,一部分比基准点小,另一部分比基准点大,然后递归地对这两部分进行排序。

代码示例:

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

时间复杂度:

  • 最优时间复杂度:O(n log n)
  • 平均时间复杂度:O(n log n)
  • 最差时间复杂度:O(n²) (当选择的基准点不合适)

快速排序是平均情况下最快的排序算法之一,但需要谨慎选择基准点。

5. 归并排序 (Merge Sort)

归并排序也是一种分治法的排序算法。它将数组分成两部分,对每一部分进行排序,然后合并两个有序的部分,直到整个数组有序。

代码示例:

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

def merge(left, right):
    result = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result.extend(left[i:])
    result.extend(right[j:])
    return result

时间复杂度:

  • 最优时间复杂度:O(n log n)
  • 平均时间复杂度:O(n log n)
  • 最差时间复杂度:O(n log n)

归并排序的优势在于稳定且在大规模数据时效率较高,缺点是需要额外的内存空间。

6. 堆排序 (Heap Sort)

堆排序是一种基于堆数据结构的排序算法。堆是一种特殊的完全二叉树,堆排序的基本思想是将数组转化为一个大顶堆(最大堆),然后从堆顶取出最大元素,将其与堆的最后一个元素交换,并对剩下的部分进行堆调整。

代码示例:

def heapify(arr, n, i):
    largest = i
    left = 2 * i + 1
    right = 2 * i + 2

    if left < n and arr[left] > arr[largest]:
        largest = left

    if right < n and arr[right] > arr[largest]:
        largest = right

    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        heapify(arr, n, largest)

def heap_sort(arr):
    n = len(arr)

    for i in range(n // 2 - 1, -1, -1):
        heapify(arr, n, i)

    for i in range(n - 1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i]
        heapify(arr, i, 0)
    return arr

时间复杂度:

  • 最优时间复杂度:O(n log n)
  • 平均时间复杂度:O(n log n)
  • 最差时间复杂度:O(n log n)

堆排序的优点在于它的空间复杂度为 O(1),且具有不错的时间复杂度。

Python内置的sorted()函数

Python 提供了内置的 sorted() 函数和列表对象的 sort() 方法,都是基于 Timsort 实现的。Timsort 是一种混合排序算法,结合了归并排序和插入排序的优点,具有非常好的性能。

代码示例:

arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
sorted_arr = sorted(arr)
arr.sort()

sorted() 函数返回一个新的已排序列表,而 sort() 方法则在原地对列表进行排序。

时间复杂度:

  • 最优时间复杂度:O(n)
  • 平均时间复杂度:O(n log n)
  • 最差时间复杂度:O(n log n)

总结

不同的排序算法在不同的场景下具有不同的优势。对于小型数据集,简单的冒泡排序、插入排序可能表现得足够好。而在大数据集下,快速排序、归并排序以及 Python 的 Timsort 通常更为合适。选择排序算法时,除了考虑时间复杂度,还应考虑算法的空间复杂度和稳定性。

通过理解和实现这些经典的排序算法,不仅能提升我们对算法的理解,还能帮助我们在实际开发中选择最合适的算法来提高程序性能。在下一课中,我们将继续深入学习Python的算法内容,进一步提升编程能力。关注我,更多精彩内容敬请期待《Python算法》系列博客的下一课–Python深度优先搜索!


http://www.kler.cn/a/286286.html

相关文章:

  • 指针(C语言)从0到1掌握指针,为后续学习c++打下基础
  • 【NEXT】网络编程——上传文件(不限于jpg/png/pdf/txt/doc等),或请求参数值是file类型时,调用在线服务接口
  • 从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(动态菜单组件实现)
  • floodfill算法(6题)
  • 算法每日双题精讲 —— 前缀和(【模板】一维前缀和,【模板】二维前缀和)
  • Golang笔记——常用库context和runtime
  • 前端提高Web/App/小程序开发效率的工具
  • CSS 的值与单位——WEB开发系列21
  • 【高阶数据结构】图的应用--最小生成树
  • 考研系列-408真题数据结构篇(10-17)
  • 003-LoadBalancer负载均衡服务调用
  • 钉钉-即时通讯-工作通知
  • 【ragflow】安装2:源码安装依赖
  • NVI技术创新联盟成立,BOSMA博冠IP轻量化制播已运用
  • 计算机毕业设计选题推荐-传统文化网站-Java/Python项目实战
  • 【Hot100】LeetCode—74. 搜索二维矩阵
  • SpringBoot——请求响应(简单参数、实体参数、数组集合参数、日期参数、JSON参数、路径参数、统一响应结果)
  • MySQL——事务与存储过程(一)事务管理(2)事务的提交
  • 商圣集团:数字创新,引领智慧生活新篇章
  • IM即时通讯软件,企业即时通讯系统就选WorkPlus
  • Unet改进17:添加ShuffleAttention||减少冗余计算和同时存储访问
  • 布偶猫应该怎么喂?希喂、交响乐金罐、尾巴生活彩虹泥适合布偶猫吗?
  • 将vue项目打包为安卓软件
  • 二元分类逻辑回归python代码实现
  • 【知识图谱】4、LLM大模型结合neo4j图数据库实现AI问答的功能
  • 【最全最详细】RPC与HTTP的区别