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

【算法】排序算法

排序算法是计算机科学中用于将一组数据按一定顺序重新排列的算法。常见的排序算法主要有以下几种,每种算法有其优缺点和适用场景。以下是几种常用的排序算法及其简要介绍:

1. 冒泡排序(Bubble Sort)

原理:重复地遍历待排序的序列,每次比较相邻的元素并交换它们的位置,使得每一趟遍历都会将当前未排序部分中最大的元素“冒泡”到最后。

时间复杂度:O(n^2)

代码示例

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

特点:简单直观,但效率较低,适合小规模或近乎有序的数据。

2. 选择排序(Selection Sort)

原理:每次从未排序的部分中找到最小(或最大)的元素,放到已排序部分的末尾。这样在排序的过程中,已排序部分逐渐变长,未排序部分逐渐缩短。

时间复杂度:O(n^2)

代码示例

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

特点:不稳定排序,交换次数少,但效率低,适合数据量小的情况。

3. 插入排序(Insertion Sort)

原理:将未排序的元素插入到已排序部分的适当位置,类似于玩扑克牌时整理手牌的过程。

时间复杂度:O(n^2)

代码示例

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

特点:稳定排序,适合小规模数据或部分有序的数据,效率比冒泡排序高。

4. 快速排序(Quick Sort)

原理:选择一个“基准”元素,将序列划分为小于和大于该基准的两个部分,分别递归地排序这两个部分。

时间复杂度:平均 O(n log n),最坏 O(n^2)

代码示例

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)

特点:通常是最快的排序算法之一,但不稳定,且在最坏情况下(如数组已排序)会退化。

5. 归并排序(Merge Sort)

原理:将数组分成两半,分别排序后合并两个有序部分,递归地应用此过程直到只剩一个元素。

时间复杂度:O(n log n)

代码示例

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

特点:稳定排序,适合大规模数据的排序,但需要额外的存储空间。

6. 堆排序(Heap Sort)

原理:构建一个最大堆(或最小堆),每次将堆顶元素放到已排序部分的末尾,并调整堆。

时间复杂度:O(n log n)

代码示例

def heap_sort(arr):
    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)
    
    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

特点:不稳定排序,适合大规模数据的排序,不需要额外的存储空间。

7. 基数排序(Radix Sort)

原理:按位数对数据进行多次排序,从最低位到最高位逐位排序,常用于整数排序。

时间复杂度:O(d ⋅ (n + k)) (其中 d 是位数,k 是基数)

代码示例

def radix_sort(arr):
    max_num = max(arr)
    exp = 1
    while max_num // exp > 0:
        counting_sort(arr, exp)
        exp *= 10

def counting_sort(arr, exp):
    n = len(arr)
    output = [0] * n
    count = [0] * 10
    for i in range(n):
        index = arr[i] // exp
        count[index % 10] += 1
    for i in range(1, 10):
        count[i] += count[i - 1]
    for i in range(n - 1, -1, -1):
        index = arr[i] // exp
        output[count[index % 10] - 1] = arr[i]
        count[index % 10] -= 1
    for i in range(n):
        arr[i] = output[i]

特点:适用于整数排序,速度快,且对一定范围内的数效率高。属于稳定排序。

总结

不同排序算法在不同情况下各有优缺点:

  • 冒泡排序、选择排序、插入排序:简单,适合小数据集或已部分排序的数据。
  • 快速排序、归并排序:高效,适合大规模数据,但需要注意最坏情况(快排)和空间消耗(归并)。
  • 堆排序:时间复杂度稳定,不需要额外空间,但不稳定。
  • 基数排序:适合范围内的整数排序,速度快且稳定。

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

相关文章:

  • 河南省的一级科技查新机构有哪些?
  • windows 11编译安装ffmpeg(包含ffplay)
  • 高性能分布式缓存Redis-高可用部署
  • TVM计算图分割--分割方式
  • 游戏引擎学习第五天
  • 前端入门一之ES6--面向对象、够着函数和原型、继承、ES5新增方法、函数进阶、严格模式、高阶函数、闭包
  • 使用layui过程中的问题
  • STM32各模块
  • 21. 评估架构
  • 快速上手Cellranger
  • 股票投资学习路线图
  • 西南科技大学竞赛与实践——实验一Paillier算法及其实现
  • Spring-Day8
  • Gradle命令编译Android Studio工程项目并签名
  • OJ算法练习(双指针篇)
  • django+postgresql
  • 题目:Wangzyy的卡牌游戏
  • 前端入门一之CSS知识详解
  • SpringBoot续+SpringMVC入门介绍
  • 二开CS—上线流量特征shellcode生成修改模板修改反编译打包
  • [QUIC] QUIC Frames
  • (C++回溯算法)微信小程序“开局托儿所”游戏
  • 图为科技与广东省北斗移动物联网产业研究院达成战略合作
  • mp3格式音频怎么做成二维码?扫码获取音频文件的制作方法
  • MySQL:客户端工具创建数据库
  • 25浙江省考-28天学行测-Day1