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

目录

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

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

1. 冒泡排序 (Bubble Sort)

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

代码示例:

python 复制代码
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)

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

代码示例:

python 复制代码
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)

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

代码示例:

python 复制代码
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),将数组分为两部分,一部分比基准点小,另一部分比基准点大,然后递归地对这两部分进行排序。

代码示例:

python 复制代码
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)

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

代码示例:

python 复制代码
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)

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

代码示例:

python 复制代码
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 是一种混合排序算法,结合了归并排序和插入排序的优点,具有非常好的性能。

代码示例:

python 复制代码
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深度优先搜索!

相关推荐
382427827几秒前
python:正则表达式
前端·python·正则表达式
锐学AI13 分钟前
从零开始学LangChain(二):LangChain的核心组件 - Agents
人工智能·python
风送雨21 分钟前
多模态RAG工程开发教程(上)
python·langchain
棒棒的皮皮23 分钟前
【OpenCV】Python图像处理形态学之膨胀
图像处理·python·opencv·计算机视觉
代码游侠24 分钟前
应用——MPlayer 媒体播放器系统代码详解
linux·运维·笔记·学习·算法
小草cys27 分钟前
HarmonyOS Next调用高德api获取实时天气,api接口
开发语言·python·arkts·鸿蒙·harmony os
爬山算法27 分钟前
Netty(25)Netty的序列化和反序列化机制是什么?
开发语言·python
未知数Tel30 分钟前
Dify离线安装插件
python·阿里云·pip·dify
龘龍龙31 分钟前
Python基础学习(六)
开发语言·python·学习
学编程就要猛36 分钟前
算法:3.快乐数
java·算法