为啥说选择排序是不稳定的

简介: 选择排序是一种简单但不稳定的排序算法。它通过每轮选择最小元素并交换位置来实现排序,但这种交换可能破坏相同值元素的相对顺序。例如对数组 `[5, 8, 5, 2]` 排序后,两个 `5` 的顺序会发生变化,从而证明其不稳定性。

选择排序被认为是不稳定的排序算法,主要是因为在排序过程中,它会通过交换元素位置来将最小(或最大)的元素放到正确的位置,而这种交换操作可能会破坏具有相同值的元素之间的相对顺序。

原理分析

选择排序的基本思想是:每一轮从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置(或末尾位置),然后再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾,以此类推,直到全部待排序的数据元素排完。

在这个过程中,选择排序会不断地将当前未排序部分的最小元素与未排序部分的第一个元素交换位置。这种交换操作是导致选择排序不稳定的关键原因。

实例说明

假设有一个数组 [5, 8, 5, 2],我们使用选择排序对其进行升序排序:

  1. 初始状态[5, 8, 5, 2]
  2. 第1轮:找到最小元素 2,与第一个元素 5 交换位置,得到 [2, 8, 5, 5]
  3. 第2轮:从剩余元素 [8, 5, 5] 中找到最小元素 5,与第一个元素 8 交换位置,得到 [2, 5, 8, 5]
  4. 第3轮:从剩余元素 [8, 5] 中找到最小元素 5,与第一个元素 8 交换位置,得到 [2, 5, 5, 8]

在这个例子中,原数组中的两个 5 的相对顺序被改变了。初始时,第一个 5 在第二个 5 之前,但经过排序后,第二个 5 被交换到了第一个 5 之前。这就说明选择排序没有保持相等元素的相对顺序,因此它是不稳定的。

代码验证

下面是选择排序的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

# 测试用例
arr = [5, 8, 5, 2]
sorted_arr = selection_sort(arr)
print("排序前:", [5, 8, 5, 2])
print("排序后:", sorted_arr)

运行这段代码,输出结果为:

排序前: [5, 8, 5, 2]
排序后: [2, 5, 5, 8]

可以看到,排序后的两个 5 的顺序与原始顺序相比发生了变化,这验证了选择排序的不稳定性。

目录
相关文章
|
5月前
|
缓存 并行计算 搜索推荐
快速排序还有哪些优化手段
快速排序性能依赖基准选择与分区策略,常见优化包括随机基准、三数取中、小规模插入排序、尾递归优化、三路快排、并行化、混合排序等,提升效率与稳定性,适用于不同场景,使快排成为高效排序算法之一。
198 0
|
5月前
|
缓存 Java
对比 synchronized 和 volatile
`synchronized` 和 `volatile` 是 Java 并发编程中的两个关键机制,各有侧重。`synchronized` 用于实现线程的互斥访问,保证原子性、可见性和有序性,适用于需要锁的场景;而 `volatile` 更轻量,仅确保变量的可见性和有序性,适用于状态标志等无需复合操作的场景。两者可互补使用,如双重检查单例中结合二者优势。合理选择有助于提升并发性能与代码安全性。
249 0
|
Rust IDE NoSQL
Clion2022安装破解与激活教程,亲测可用
CLion是JetBrains公司旗下发布的一款跨平台C/C++/Rust IDE开发工具。
13638 1
|
缓存 JavaScript 算法
vue2和vue3之间diff算法的差异
vue2和vue3之间diff算法的差异
|
5月前
|
Java 应用服务中间件 Maven
SpringBoot使用汇总
本节介绍了Spring Boot项目工程结构,包含src/main/java(业务代码)、src/main/resources(静态与配置文件)和src/test/java(测试代码)。通过@SpringBootApplication注解的启动类运行main方法即可快速启动应用。Spring Boot内置Tomcat,简化配置流程。示例展示了创建Controller、访问接口及修改默认端口的方法,帮助开发者快速上手Spring Boot开发。
164 2
|
5月前
|
缓存 前端开发 NoSQL
什么是缓存雪崩?
缓存雪崩是指大量缓存key在同一时间失效,或缓存服务整体故障,导致请求全部转向数据库,造成数据库压力剧增甚至宕机。其特点是失效具有“批量性”和“突发性”,可能引发系统级联故障。常见场景包括大量key集中过期或缓存服务崩溃。相比缓存击穿,雪崩影响范围更广、危害更大,可能导致业务中断,如电商大促时订单系统瘫痪。
169 0
|
5月前
|
分布式计算 关系型数据库 MySQL
【赵渝强老师】大数据交换引擎Sqoop
Sqoop是一款开源工具,用于在Hadoop与传统数据库如Oracle、MySQL之间传输数据。它基于MapReduce实现,支持数据导入导出、生成Java类及Hive表结构等操作,适用于大数据处理场景。
153 3
【赵渝强老师】大数据交换引擎Sqoop
数据结构堆排序中堆的建立、调整、插入、删除等操作的详解(题目讲解 简单易懂)
数据结构堆排序中堆的建立、调整、插入、删除等操作的详解(题目讲解 简单易懂)
1043 0
|
存储 网络协议 数据安全/隐私保护
OSI七层模型 (详细讲解,看这一篇就够了)
OSI七层模型 (详细讲解,看这一篇就够了)
12089 0
|
存储 JavaScript 前端开发
js中的遍历方法比较:map、for...in、for...of、reduce和forEach的特点与适用场景
js中的遍历方法比较:map、for...in、for...of、reduce和forEach的特点与适用场景
721 0

热门文章

最新文章