选择排序算法详解 - itcharge/LeetCode-Py项目解析

选择排序算法详解 - itcharge/LeetCode-Py项目解析

LeetCode-Py ⛽️「算法通关手册」:超详细的「算法与数据结构」基础讲解教程,从零基础开始学习算法知识,800+ 道「LeetCode 题目」详细解析,200 道「大厂面试热门题目」。 LeetCode-Py 项目地址: https://gitcode.com/gh_mirrors/le/LeetCode-Py

1. 选择排序算法核心思想

选择排序是一种基于比较的简单排序算法,其核心思想可以概括为"每次选择最小的元素放到已排序序列的末尾"。这种算法将待排序数组分为两个部分:

  • 已排序区间:位于数组左侧,初始为空
  • 未排序区间:位于数组右侧,包含所有待排序元素

算法的每一轮都会从未排序区间中找出最小元素,然后将其与未排序区间的第一个元素交换位置,从而将该元素纳入已排序区间。这个过程不断重复,直到未排序区间为空。

2. 选择排序详细执行过程

让我们通过一个具体的例子来理解选择排序的执行步骤。假设我们要排序的数组是 [5, 2, 3, 6, 1, 4]

初始状态

  • 已排序区间:[]
  • 未排序区间:[5, 2, 3, 6, 1, 4]

第一轮排序

  1. 遍历未排序区间,找到最小值 1(位于索引4)
  2. 将最小值 1 与未排序区间第一个元素 5 交换
  3. 结果:
    • 已排序区间:[1]
    • 未排序区间:[2, 3, 6, 5, 4]

第二轮排序

  1. 在剩余未排序区间中找到最小值 2(位于索引1)
  2. 由于 2 已经是未排序区间的第一个元素,无需交换
  3. 结果:
    • 已排序区间:[1, 2]
    • 未排序区间:[3, 6, 5, 4]

后续轮次

按照同样的方式继续处理,直到所有元素都进入已排序区间。完整的排序过程如下:

  1. [1, 2, 3, 6, 5, 4]
  2. [1, 2, 3, 6, 5, 4](3已在正确位置)
  3. [1, 2, 3, 4, 5, 6]
  4. [1, 2, 3, 4, 5, 6](5已在正确位置)
  5. [1, 2, 3, 4, 5, 6](6已在正确位置)

3. 选择排序的Python实现

在itcharge/LeetCode-Py项目中,选择排序的实现采用了面向对象的方式,封装在Solution类中:

class Solution:
    def selectionSort(self, nums: [int]) -> [int]:
        for i in range(len(nums) - 1):
            # 记录未排序区间中最小值的位置
            min_i = i
            for j in range(i + 1, len(nums)):
                if nums[j] < nums[min_i]:
                    min_i = j
            # 交换元素位置
            if i != min_i:
                nums[i], nums[min_i] = nums[min_i], nums[i]
        return nums

代码解析

  1. 外层循环:控制排序轮次,i表示已排序区间的末尾位置
  2. 内层循环:在未排序区间[i+1, len(nums)-1]中寻找最小值的位置
  3. 交换操作:将找到的最小值与未排序区间的第一个元素交换
  4. 优化点:当i == min_i时,说明元素已在正确位置,无需交换

4. 选择排序的性能分析

时间复杂度

  • 最坏情况:O(n²)
  • 最好情况:O(n²)
  • 平均情况:O(n²)

选择排序的时间复杂度始终是O(n²),因为无论输入数据的初始顺序如何,算法都需要执行完整的n(n-1)/2次比较。

空间复杂度

  • O(1),是原地排序算法,仅需要常数级别的额外空间

稳定性

选择排序是不稳定的排序算法。考虑数组[5, 8, 5, 2, 9],第一个5会和2交换位置,导致两个5的相对顺序改变。

5. 选择排序的适用场景

虽然选择排序的时间复杂度较高,但在某些特定情况下仍有其优势:

  1. 小规模数据:当数据量较小时,选择排序的简单性使其成为不错的选择
  2. 空间受限环境:由于是原地排序,不需要额外存储空间
  3. 特定硬件:在某些硬件架构中,交换操作比比较操作代价更高时,选择排序可能更优(因为它每轮最多只交换一次)

6. 选择排序的变体

在实际应用中,选择排序有一些常见的变体:

  1. 双向选择排序:同时寻找未排序区间中的最小值和最大值,分别放到已排序区间的两端
  2. 堆排序:利用堆数据结构来优化选择最小元素的过程,将时间复杂度降低到O(nlogn)

7. 选择排序与其他排序算法的比较

| 特性 | 选择排序 | 冒泡排序 | 插入排序 | |------|----------|----------|----------| | 时间复杂度 | O(n²) | O(n²) | O(n²) | | 空间复杂度 | O(1) | O(1) | O(1) | | 稳定性 | 不稳定 | 稳定 | 稳定 | | 交换次数 | O(n) | O(n²) | O(n²) | | 比较次数 | O(n²) | O(n²) | O(n²) |

从表中可以看出,选择排序的交换次数较少,这是它的一个优势。

8. 总结

选择排序作为最基础的排序算法之一,虽然在实际应用中效率不高,但它的简单性和直观性使其成为学习排序算法的良好起点。理解选择排序的工作原理有助于掌握更复杂排序算法的设计思想。在itcharge/LeetCode-Py项目中,选择排序的实现展示了如何用Python简洁地表达这一算法,为学习其他排序算法奠定了基础。

LeetCode-Py ⛽️「算法通关手册」:超详细的「算法与数据结构」基础讲解教程,从零基础开始学习算法知识,800+ 道「LeetCode 题目」详细解析,200 道「大厂面试热门题目」。 LeetCode-Py 项目地址: https://gitcode.com/gh_mirrors/le/LeetCode-Py

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贡锨庆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值