选择排序及其优化方案

【排序】选择排序(含优化版) 冒泡排序的时间复杂度为O(n^2),其中n是要排序的元素数量。这是因为冒泡排序需要进行多次遍历,每次遍历都需要比较和交换元素。因此,对于大规模数据的排序,冒泡排序可能不是最有效的选择。选择排序的时间复杂度也是O(n^2),但它的性能通常优于冒泡排序。因为选择排序只需要进行一次遍历,并且只需要进行一次比较和交换操作。因此,在处理大规模数据时,选择排序通常更为高效。但如果遇到已经排好序的数据,冒泡排序只需要循环一次就能发现,并终止,但选择排序却需要继续遍历数组,在这一点上选择排序的效率是不如冒泡排序的。 阅读详情

选择排序

  1. 基本思想
  2. 运行轨迹
  3. 代码实现
  4. 性能分析
  5. 优化方案

1、基本思想

这是一种思路最简单的排序算法。

①、找到数组中最小的那个元素
②、将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)
③、在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置
④、重复执行③,直到将整个数组排序。

为什么叫选择排序?就是因为它在不断地选择剩余元素之中的最小者。


2、运行轨迹

这里写图片描述


3、代码实现

根据排序算法类的模板实现选择排序(提醒:点蓝字查看详情)

/**
 * 选择排序
 *
 * @author TinyDolphin
 *         2017/5/14 19:20.
 */
public class Selection {
    /**
     * 排序实现
     * @param arr 待排序数组
     */
    public static void sort(Comparable[] arr) {
        int length = arr.length;//数组长度
        for (int indexI = 0; indexI < length; indexI++) {
            //将arr[indexI]和arr[indexI+1...length]中最小的元素交换
            int min = indexI;//最小元素的索引
            for (int indexJ = indexI + 1; indexJ < length; indexJ++) {
                if (less(arr[indexJ], arr[min])) {
                    min = indexJ;
                }
            }
            exch(arr, indexI, min);
        }
    }
    /**
     * 比较两个元素的大小
     * @param comparableA 待比较元素A
     * @param comparableB 待比较元素B
     * @return 若 A < B,返回 true,否则返回 false
     */
    private static boolean less(Comparable comparableA, Comparable comparableB) {
        return comparableA.compareTo(comparableB) < 0;
    }
    /**
     * 将两个元素交换位置
     * @param arr 待交换元素所在的数组
     * @param indexI 第一个元素索引
     * @param indexJ 第二个元素索引
     */
    private static void exch(Comparable[] arr, int indexI, int indexJ) {
        Comparable temp = arr[indexI];
        arr[indexI] = arr[indexJ];
        arr[indexJ] = temp;
    }
    /**
     * 打印数组的内容
     * @param arr 待打印的数组
     */
    private static void show(Comparable[] arr) {
        for (int index = 0; index < arr.length; index++) {
            System.out.print(arr[index] + " ");
        }
        System.out.println();
    }

    /**
     * 判断数组是否有序
     * @param arr 待判断数组
     * @return 若数组有序,返回 true,否则返回 false
     */
    public static boolean isSort(Comparable[] arr) {
        for (int index = 1; index < arr.length; index++) {
            if (less(arr[index], arr[index - 1])) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        Integer[] arr = new Integer[]{14, 23, 21, 17, 20, 49, 24, 77, 54, 47, 31};
        sort(arr);
        assert isSort(arr);
        show(arr); //14 17 20 21 23 24 31 47 49 54 77 
    }
}

4、性能分析

交换元素的代码写在内循环之外,每次交换都能排定一个元素,因此交换的总次数是N。所以算法的时间效率取决于比较的次数。

查看代码可以精准得到,0 到 N-1 的任意 indexI 都会进行一次交换和 N-1-indexI次比较,所以对于长度为 N 的数组,选择排序需要大约 N²/2 次比较和 N 次交换。

选择排序的特点:
①、运行时间和输入无关。为了找出最小的元素而扫描一遍数组并不能为下一遍扫描提供什么信息;
②、数据移动是最小的。每次交换都会改变两个数组元素的值,因此选择排序用了 N 次交换——交换次数和数组的大小是线性关系。(其他大部分排序算法的增长数量级都是线性对数或是平方级别的)


5、优化方案

试想,上述方案中的主要思路是,每次遍历剩余元素,找出其中最小值,只排定最小值。

我们这样,每次遍历剩余元素的时候,找出其中最小值和最大值,并排定最小值和最大值。

这样遍历的次数会减少一半。时间复杂度是O(N/2 * N /2),还是平方级别的。但是运行时间有了相应的减少。

方案修改之后的运行轨迹

这里写图片描述

优化代码

public static void sortPlus(Comparable[] arr) {
    for (int left = 0, right = arr.length - 1; left < right; left++, right--) {
        int min = left;
        int max = right;
        for (int index = left; index <= right; index++) {
            if (less(arr[index], arr[min])) {
                min = index;
            }
            if (less(arr[max], arr[index])) {
                max = index;
            }
        }
        exch(arr, left, min);
        //此处是先排最小值的位置,所以得考虑最大值(arr[max])在最小位置(left)的情况。
        if (left == max) {
            max = min;
        }
        exch(arr, right, max);
    }
}

测试用例

public static void main(String[] args) {
    int length = 100000; //十万级别
    Integer[] arr = new Integer[length ];
    for (int index = 0; index < length ; index++) {
        arr[index] = new Random().nextInt(length ) + 1;
    }
    long start = System.currentTimeMillis();
    //sort(arr);   //十万级别-耗费时间:83001ms
    sortPlus(arr); //十万级别-耗费时间:54857ms
    long end = System.currentTimeMillis();
    System.out.println("耗费时间:" + (end - start));
    assert isSort(arr);
}

最后,虽然排序算法简单,但是其优化方案是非常好的一个优化思路,也可以考虑使用在别的算法上,不要仅仅局限于此。

注意:编译器默认不适用 assert 检测(但是junit测试中适用),所以要使用时要添加参数虚拟机启动参数-ea
具体添加过程,请参照eclipse 和 IDEA 设置虚拟机启动参数

三臂杆大型液压机械臂集中式ADRC控制系统设计 本文设计了一种用于三臂杆液压机械臂的集中式自抗扰控制(ADRC)系统。该系统通过建立包含惯性矩阵、科氏力、重力及摩擦力的非线性动力学模型,并集成液压系统传递函数,构建了完整的系统模型。控制方案采用跟踪微分器安排过渡过程,扩张状态观测器实时估计系统状态和总扰动,以及非线性状态误差反馈生成控制量。MATLAB实现展示了集中式ADRC控制器的核心结构,包括参数定义、跟踪微分器、扩张状态观测器和非线性反馈模块的设计。该系统能有效处理多关节耦合效应,实现三输入三输出的MIMO控制,具有抗干扰能力强、响应速度快的特点。 阅读详情

相关推荐

C# typeof() 和 GetType()区别

总得来说他们都是为了获取某个实例具体引用的数据类型System.Type。 1、GetType()方法继承自Object,所以C#中任何对象都具有GetType()方法,x.GetType(),其中x为变量名,由x实例返回得到一个类型 2、typeof(x)中的x,必须是具体的类名、类型名称等,不可以是变量名称,返回一个类型 3、System.Type.GetType(),有两个重载方法 比如有这样一个变量i: Int32 i = new Int32(); 使用GetType(),i...

Peter的博客 1954

选择排序及优化

目录 一、普通实现 二、模板实现 三、优化版本一 四、优化版本二 和冒泡排序区别:冒泡排序是逐步对相邻元素进行操作(比较和交换位置)。而选择排序是从待排序数列中选择最大/小值,再将之放置到已排序数列中。 (有序区,无序区)。在无序区里找一个最小的元素跟在有序区后面。对数组:比较的多,换的少。 选择排序思路: 1、在未排序序列中找到最小(大)元素,...

幻欢子 3197

模型检测--工具KeYmaera

论文:KeYmaera: A Hybrid Theorem Prover for Hybrid Systems 作者:Andre Platzer and JanKeYmaera摘要1 介绍2用于混合系统的KeYmaera验证工具3混合系统,混合自动机和混合程序 摘要 KeYmaera是一种用于混合系统的混合验证工具,它结合了演绎,实数代数和计算机代数证明者技术。它是自然的自动和交互式定理证明器 混合系统的规范和验证逻辑。 KeYmaera支持差分动态逻辑,它是用于混合程序的实值一阶动态逻辑,是混合自动机的程

ziigea的博客 1076

图解选择排序算法及优化

3分钟学会选择排序算法及其优化

chenchenchencl的博客 7020

LangChain学习及应用(超详细)

Model I/O 部分是与语言模型进行交互的核心组件,包括输入提示(Prompt Template)、调用模型(Model)、输出解析(Output Parser)。简单来说,就是输入、处理、输出这三个步骤。LLM 因其具有海量参数,需要花费相当的物力与时间成本进行预训练和微调,同时商用 LLM 还需要进行各种安全测试与风险评估等。因此 LLM 会存在知识滞后的问题。在专有领域,LLM 无法学习到所有的专业知识细节,因此在面向专业领域知识的提问时,无法给出可靠准确的回答。

weixin_39764056的博客 4233

GEE|基于时间序列特征的山东省玉米随机森林分类代码

主题思路: 本实验为二分类实验,分类目标包括:玉米、其他(建筑、水体、水稻、 裸地、森林、小麦、道路、大蒜等),采用人工设计的特征指数的时间序列特征为分类依据,选取分类器为:随机森林分类器,并选取样本集中 70%作为训练样本,30%作为测试样本,通过调整随机森林棵数,调整分类器结构。选取以下参数进行分类: ⚫ 时间尺度:1990 年 4 月 15 日 - 1990 年 9 月 30 日 ⚫ 空间尺度:山东省 ⚫ 影像融合时间间隔:16天 ⚫ 特征值选择:['nir','ndvi'...

weixin_46493028的博客 7466

十大经典排序算法之选择排序及其优化

一、简单选择排序 1.基本思想: 在长度为N的无序数组中,第一次遍历n-1个数,找到最小的数值与第一个元素交换; 第二次遍历n-2个数,找到最小的数值与第二个元素交换; 。。。 第n-1次遍历,找到最小的数值与第n-1个元素交换,排序完成。 2.过程 3.代码 public static void selectSort(int[] arr) { int minNum = 0; int temp = 0; int a = 0; for (i

Kevinnsm的博客 1220

基于LLM【M3】驱动的自动化攻击智能体AK(受控使用)

摘要:文章实测了基于大模型的目标驱动型云攻击智能体,展示攻击者仅需输入业务目标(如"窃取BigQuery数据")即可自动完成SSRF、令牌解析、数据导出等全链条攻击。研究发现:(1)攻击编排范式已从固定脚本升级为自适应路径;(2)传统基于IOC的防御与新型攻击存在结构性错位;(3)防御需转向元数据加固、跨服务行为序列检测和AI驱动的紫队演练。实验在授权靶场使用合成数据,验证了攻击智能体"监督者模型+专业执行组"的协作模式,强调防御体系需从单点检测升级为攻击链理解能力。

云上笛暮 306

排序算法-选择排序及其优化

Select Sort

Weber's blog 1873

面试官连夜整理:103道AI Agent面试题,答对一半直接加薪50%

维度AutoGPTLangGraphAutoGen控制流LLM 驱动的隐式循环代码层定义的显式状态图对话驱动的自动流转状态存储Prompt 上下文中(易丢失)结构化 State 对象(可持久化)对话历史(自动累积)分支能力依赖 LLM 的文本输出(不稳定)条件边 + 节点路由(确定性)多 Agent 对话自然分支(涌现式)回溯/回滚无原生支持,只能重新开始原生 Checkpoint 支持时间旅行无全局回滚,单 Agent 可重启人机协同仅人工在关键点介入(需要自定义)原生支持。

weixin_35774598的博客 620

SAP 与 Palantir 合作全景解析:这不是普通集成,而是把 ERP、数据语义层、云迁移与企业级 AI 串成一条价值链

SAP与Palantir的战略合作聚焦企业数字化转型核心痛点,通过深度技术整合构建"数据-决策-执行"闭环。合作包含四大主线:云迁移连续性保障、SAP业务数据云与Palantir平台对接、联合工程开发、高监管行业优先落地。技术实现上采用SAP认证插件,支持双向数据交互和实时业务动作触发。该合作突破了传统ERP系统局限,将业务语义与AI执行相结合,特别适合制造业供应链优化、财务争议处理等高价值场景,为企业在云迁移过程中实现业务连续性与智能化升级提供新范式。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 192

选择排序及其优化

选择排序是八大内部排序方法中的一种,选择排序的整体的思想就是,我们在一个序列当中选出一个最大的(升序为最小的),然后和第一个元素交换,然后后面再在剩下的找最大的,再和第二个元素交换。这样最终就可以得到一个有序的序列。我们最先接触的就是这种写法。//Cpp版本 template<typename T> void SelectSort(T* arr,int n) { int max = 0;

宇哲 1万+

【华为OD机试真题 新系统】1009、企业内部门的最大层级 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)

【华为OD机试真题 新系统】1009、企业内部门的最大层级 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS) 华为od机试,华为od机试真题,华为od机试E卷,华为odE卷,华为od机试真题E卷,华为OD,华为OD机试,华为OD机试真题,华为od机考,华为od机试D卷,华为od机试真题D卷,华为od手撕代码,华为od,华为od机试C卷,华为od e卷,华为2026e卷,od机试,2026E卷,华为OD机试E卷,什么是华为od,华为od介绍,全面了解华为od,2026华为od,如何备战

KJ.JK 1412

直接选择排序和它的优化

直接选择排序是一种比较直观的排序,它是从一个无序的额数组中选择一个最小或最大的并将这个最大的放在数组的开始或末尾,现在进行代码的实现: /****/ if (parr [j] /********************/ 现在这个选择排序还有很大的优化空间,上述的方法的时间复杂度为O(n^2)。现在的优化方式是同时选出他的最大的和最小的。 代码实现: void Se

qingqiulengya的博客 1581

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

选择排序(selection sort)及其优化方式(java)

对于排序算法,我们可以写出多种方式以达到我们想要的效果,但在这些不同的方法中,有的排序方法效率低,有的排序方法效率高,我们想当然的会选择效率高的排序方法。以下是简单的选择排序和优化后的选择排序等两种方法。

2302_80918353的博客 678

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

选择排序及其优化(Java版)

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

眠可欣的博客 482

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

选择排序及简单优化

正常选择排序 从待排序的数组中,找到下标最小的元素 k=i 从i+1开始找,找到比它大的数 k=j 交换下标为i和下标为k的数 #include<bits/stdc++.h> using namespace std; const int n=10; int main(){ //初始化数组 int a[n]={1,3,45,90,8,5,5,6,2,33}; //输出原数组 for(int i=0;i<n;i++){ cout<<a[i]<<"

qq_45700119的博客 157

排序算法之直接选择排序【图文详解】

本文主要讲述数据结构排序算法中的直接选择排序,附有图文详解。

LiU11e的博客 1780

2-选择排序

文章目录 1 选择排序介绍 2 基本选择排序 3 选择排序的优化 3.1 二元选择排序 3.2 同时排序最大和最小值 3.3 索引混乱 3.4 代码优化 1 选择排序介绍 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是:首先在未排序序列中找到最小(大)元素...

大欣的IT之路 282

排序二:选择排序及优化

  原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕。也就是:每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录    作为有序序列中第i个记录。基于此思想的算法主要有简单选择排序、树型选择排序和堆排序。(这里只介绍常用的简单选择排序) 简单选择排序的基本思想:给定数组:int[]arr={里面n个数据};第1趟排序,在待排...

weixin_34174105的博客 107

JAVA实现--基础算法FOR选择排序

首先 实现简单的选择排序。 简单排序的思路很简单,就是通过遍历(数组的length次)的数组,每次遍历找出最小的放到数组的第一个位置,下次遍历时就不用考虑第0位置的数从第1的位置开始找1到length中最小的数。。。 实现最简单的选择排序 1 //实现选择排序的方法 2 public static int[] selSort(int[] arr){ ...

aihaozhe6621226的博客 227

选择排序算法java_图解选择排序及算法优化(Java实现)

选择排序前言原理:每次循环对比找出最小/大值,将最值的元素交换至左侧思想:直接选择排序(Straight Select Sort)算法思想:第一趟从n个元素的数据序列中选出关键字最小/大的元素并放在最前/后位置,下一趟从n-1个元素中选出最小/大的元素并放在最前/后位置。以此类推,经过n-1趟完成排序案例分析:1、初始的无序数列 {5,8,6,3,1,7},希望对其升序排序2、按照思路分析:内层循...

weixin_30356837的博客 214

选择排序简单介绍

1、选择排序原理 选择排序的工作原理:第一次找出未排序的数组元素中的最大或者最小的值,存放在数组中的第一个,这样数组中的第一个元素就排序完成,然后在剩下的元素中再次找出最大值或者最小值,放在数组的第二个位置。依次对后面未进行排序的数组元素采取相同的操作,直到所有元素排序完成。 用代码实现选择排序的例子:(以升序排序为例) void selectionSort(int arr[],int len) { //代表排序要进行的躺数 数组长度-1次 for (int i = 0; i < len

m0_61694515的博客 772

排序算法——选择排序系列及性能测试

初识选择排序 选择排序是一种和冒泡排序一样简单的排序算法。它的思想非常简单,假设数组大小为n,每次从数组的待排序部分中选出一个最小的元素,放到数组最左侧,n轮筛选后,数组就整体有序了。 图解如下 假设准备对如下数组进行选择排序 先对数组的待排序部分进行遍历,选出最小的元素为1,将1放到数组最左侧 第二轮,对剩下的部分进行遍历,选出最小的元素为2,将2放到最左侧(和4交换) 如此以来,第三轮选出的元素是3,第四轮选出的是4…经过9轮选择后,数组整体有序 它的代码实现也非常简单 public void

vcj1009784814的博客 1034

选择法排序

选择法排序,选择法排序应该算是所有排序中最好理解的一种排序算法了。其思想是,先定位到第一个,然后再拿所有的数据跟它比较,如果比它小,就让他们作交换,然后再定位到第二个,再拿出它后面所有的数据与它相比较,如果比它小就作交换,就这样,不停的定位到第2个,第三个,一直到第n个,当定位到第n个的时候,真个就是一个顺序的数列了。如下代码: public static void sort(int[] n

花落归尘醉的专栏 1114

排序算法(二)-选择排序

0. 原理选择排序和冒泡排序一样是一种简单直观的排序算法,工作原理如下: 在未排序序列中找到最大或者最小的数字,放到最前或者最后的位置 再从剩余的序列中找到最大或者最小的数字,放到剩余序列的最前或者最后的位置 重复操作直到序列有序 对[2, 8, 1, 5, 3]这个数组排序,完整流程如下round 1 start 2 8 1 5 3 (exchange data: 2 <-> 1) 1 8 2

Zaratustra 423
上一篇: eclipse 和 IDEA 设置虚拟机启动参数
下一篇: 插入排序及其优化方案
TinyDolphin
博客等级 码龄10年 36粉丝 163原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值