【算法】选择排序

选择排序

排序: 排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

稳定性: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中, ri = rj, 且 ri 在 rj 之前,而在排序后的序列中, ri 仍在 rj 之前,则称这种排序算法是稳定的;否则称为不稳定的。
(注意稳定排序可以实现为不稳定的形式, 而不稳定的排序实现不了稳定的形式)

内部排序: 数据元素全部放在内存中的排序。

外部排序: 数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

选择排序

选择排序(Selection Sort)是一种简单的排序算法,其基本思路可以描述为:

  • 初始状态: 将待排序的数据分为两部分,一部分是已排序的部分(初始为空),另一部分是未排序的部分(初始包含所有元素)。

  • 找到最小元素: 在未排序部分中,找到最小的元素,将其与未排序部分的第一个元素交换位置,即将最小元素放到已排序部分的末尾。

  • 重复步骤: 继续以上步骤,每次在未排序部分中找到最小的元素,并将其交换到已排序部分的末尾,逐渐将所有元素都移动到已排序部分。

  • 完成排序: 当未排序部分没有元素时,排序完成,整个数据集已经按照升序(或降序)排列好了。

选择排序的核心思想是在未排序的部分中选择最小的元素,并将其放到已排序部分的末尾,逐步缩小未排序部分的范围,直到整个数据集排序完成。选择排序的时间复杂度为O(n^2),不适用于大型数据集。

代码实现

javascript 复制代码
    public static void selectSort(int[] arr) {
        int len = arr.length;
        for (int i = 0; i < len-1; i++) {
            // 假设未排序部分的第一个元素为最小
            int minIndex = i;
            // 找到未排序部分中的最小的元素
            for (int j = i+1; j < len; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }

            if (minIndex != i) {
                // 将最小元素放到未排序的最前面
                int temp = arr[i];
                arr[i] = arr[minIndex];
                arr[minIndex] = temp;
            }
        }
    }

代码优化

优化一:

同时选择最大值和最小值

javascript 复制代码
    public static void selectSort2(int[] arr) {
        int len = arr.length;
        int left = 0;
        int right = len - 1;
        while (left < right) {
            // 同时记录最大值和最小值的下标
            int minIndex = left;
            int maxIndex = left;
            // 找未排序区间中的最大值和最小值的下标
            for (int i = left + 1; i <= right; i++) {
                if (arr[i] < arr[minIndex]) {
                    minIndex = i;
                }
                if (arr[i] > arr[maxIndex]) {
                    maxIndex = i;
                }
            }
            // 确定最大值和最小值
            swap(arr, left, minIndex);
            // 当 left 下标对应的值就是最大值时, 上面这个 swap 有可能把 最大值的位置换到最小值的位置
            if (left == maxIndex) {
                maxIndex = minIndex;
            }
            swap(arr, right, maxIndex);
            // 未排序的区间减小
            left++;
            right--;
        }
    }

    public static void swap (int[] arr, int index1, int index2) {
        int temp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = temp;
    }

虽然性能有提升, 但是时间复杂度还是 O(N*N)

优化二:

堆排序是一种树形选择排序,是对直接选择排序的有效改进。
堆排序详解

总结:

  • 时间复杂度: O(N*N)
  • 空间复杂度: O(1)
  • 是不稳定排序: 举个例子,序列arr = 5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中两个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法。
  • 对数据不敏感: 没有好坏之分, 不管数据原本的分布情况, 每层循环都需要遍历一遍, 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用。

以上就是对选择排序的讲解, 希望能帮到你 !
评论区欢迎指正 !

相关推荐
海宇AI几秒前
Java数据工程:利用海宇婚恋风险报告优化高端婚恋实名与涉诉核验合规体验
java·人工智能
打码的老程是远篁2 分钟前
手把手教你玩转大模型——3. Transformer 的位置编码——模型怎么知道谁在前,谁在后?
人工智能·算法
嘎嘎风3 分钟前
MiniMind 学习笔记之 06 一张图、一百行:MiniMind 的骨架
算法·源码
CEZ6 分钟前
中小企业上 WMS 该先上哪几块:JeeWMS 开源 Java 仓库管理系统的分批上线清单
java·开源
用户7341681035487 分钟前
只盯被动响应做状态监测?论“控制信号”在变工况故障诊断中的重要作用
算法
Ivanqhz9 分钟前
MQA、GQA、稀疏/滑动窗口注意力及混合范式
人工智能·算法·机器学习
Wang's Blog15 分钟前
Java框架 SpringCloud 快速入门: Gateway 路由的过滤器配置
java·spring cloud·gateway
罗湖老棍子18 分钟前
荒岛野人(信息学奥赛一本通- P1637)(洛谷-P2421)
算法·数论·枚举·裴蜀定理·扩展欧几里得·扩展中国剩余定理
朝朝辞暮i22 分钟前
C++ 第 40 章:ROS2 Publisher + Timer + Subscriber + Callback + Executor 完整闭环
开发语言·c++·算法·ros2
400分30 分钟前
具身智能系列之从零到「机械臂会放试管」:π0.5 VLA 真机部署完全指南【第一节】
算法