排序算法总结(一)——选择排序

5. 进阶排序算法——堆排序(golang) 前言 由于博主目前还没有系统学习到二叉树相关的知识,所以有关完全二叉树的概念尽量不会提到。 下文会尝试用最最简单,最容易理解的方式进行描述。 堆排序的思想核心 前面提到的基础排序算法,他们都有一个缺点,没有把每一次的比较结果保存下来,这就导致了后续会进行重复的比较工作。 工作流程: 构建一个堆的结构; 找到堆内最大或者最小值,将其移走; 剩余的元素又组成一个新的堆。 循环往复... 阅读详情

选择排序的基本宗旨就是每次选出剩余元素中最大的或者最小放在最终排序的对应位置。

1.直接选择排序
基本思想:
在a[1]-a[n-1]中选择最小的元素和a[0]交换;
在a[2]-a[n-1]中选择最小的元素和a[1]交换;
……
在a[i]-a[n-1]中选择最下的元素和a[i-1]交换;
以此类推。。。。。。

算法步骤:
循环比较:
第一轮:将a[0]和a[1]-a[n-1]中的每个元素依次比较,若出现a[0]>a[j],则将两者进行交换;由此可以将数组中最小的元素放到a[0];
第二轮:将a[1]和a[2]-a[n-1]中的每个元素依次比较。同样若出现a[1]>a[j],则将两者交换,由此将倒数第二小的元素放到a[1];
依次类推。。。

代码实现:

public class SelectedSort {
    //测试
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] a = {2,5,1,7,4,3,6};
        sort(a);
    }
    //排序
    public static void sort(int[] a){
        //双重循环,依次比较大小
        for(int i = 0;i<a.length-1;i++){
            for(int j = i+1;j<a.length;j++){
                if(a[j]<a[i]){
                    int tmp = a[j];
                    a[j] = a[i];
                    a[i] = tmp;
                }
            }
        }
        for(int i = 0;i<a.length;i++){
            System.out.println(a[i]);
        }
    }
}

2.直接选择排序的改进
在直接选择排序中,如在第一轮比较中,一旦找到比a[0]小的元素便进行交换,这样导致最多需要n-1次比较和交换才能找到最小的元素,但是我们每轮比较的目的是选出最小的元素放到a[0]上,所以可以改进上诉的算法,在找到最小元素后再跟a[0]进行交换,这样只需要交换一次即可。

算法实现:设置一个标记为,每次标记较小的元素所在的位置,直到找到最小的元素位置,然后直接进行交换即可。

代码实现:

public class SelectedSort {

    public static void main(String[] args) {
        int[] a = {2,5,1,7,4,3,6};
        sort(a);
}

    public static void sort(int[] a){
        int minI = 0;

        for(int i = 0;i<a.length-1;i++){
            minI = i;
            for(int j = i+1;j<a.length;j++){
                if(a[j]<a[minI]){
                    minI = j;
                }
            }
            if(minI!=i){
                int tmp = a[minI];
                a[minI] = a[i];
                a[i] = tmp;
            }
        }

        for(int i = 0;i<a.length;i++){
            System.out.println(a[i]);
        }   
    }
}

3.堆排序
这篇博文介绍了堆排序,生动简单清晰,所以这里多数是参考来写的,侵权删。https://www.cnblogs.com/chengxiao/p/6129630.html

(1)堆
堆是一种特殊的几乎完全二叉树。
堆的性质:叶子结点的键值或索引总是小于(或者大于)它的父节点(大顶堆和小顶堆)。
这里写图片描述

对堆的访问:
根节点的位置为0;
父节点i的左子节点在位置 (2*i+1);
父节点i的右子节点在位置 (2*i+2);
子节点i的父节点在位置 (i-1)/2;
最后一个非叶子节点的下标是n/2-1 ,因为其为最后一个节点(n-1)的父节点。

堆结构映射为数组即为如下所示:
这里写图片描述

(2)堆排序(升序采用大顶堆,降序采用小顶堆)
基本思想:将待排序的数组构造成一个大顶堆,那么此时根节点的元素即为最大值,将其与最后一个叶子节点进行交换,即将最大元素放置在了末尾;然后将剩余的n-1个元素重新构造成一个大顶堆,依次类推,最终完成对数组的排序。

实现步骤:

A. 根据给定无序数组构造一个大顶堆。
给定的无序数据如下(设长度为n,此出n=5):
这里写图片描述
首先从最后一个非叶子节点开始调整,因为叶子节点需要跟着其父节点进行调整。第一个非叶子节点为n/2-1,即数值为6的节点。
对于堆结构来说,因为堆是一个完全二叉树,所以肯定存在左子节点,所以首先判断是否存在右子节点,若存在,则将两个子节点进行比较,将数值大的子节点再与父节点比较,进而当子节点>父节点的情况下,父节点与子节点进行交换。
如图,6和9进行交换。
这里写图片描述

找到第二个非叶子节点4,同理将4和9交换。
这里写图片描述

明显可以看出,但是这步交换导致[4,5,6]不满足堆结构,所以需要继续调整。
这里写图片描述
至此,成功构成一个大顶堆。

B.将根节点和最后一个叶子节点进行交换,并且需要对n-1个元素继续调整成堆(从根节点开始调整,因为除了根节点外其他均已满足堆结构),以此类推,不断进行交换,重建。。。。。。
将4和9进行交换
这里写图片描述

重新构建大顶堆
这里写图片描述

将8和5交换
这里写图片描述

以此接着调整和交换,最终得到如下有序序列
这里写图片描述

堆排序基本思路总结:
a. 首先从最后一个非叶子节点,从右至左,从下至上,将无序序列构建成一个大顶堆;
b.将根节点与最后一个叶子节点进行交换,得到最大元素;
c.因为根节点发生了变化,其他父节点均满足堆结构,所以从根节点开始调整,将剩余元素继续构造成大顶堆,并交换根节点和最后一个叶子节点,直到完成排序。

代码实现如下:

public class HeapSort1 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] a = {2,3,1,4,6,0};
        sort(a);
        for(int i = 0;i<a.length;i++)
            System.out.println(a[i]);

    }

    public static void sort(int[] a){
        int n = a.length;
        int t = 0;

        //初始化大根堆,从最后一个非叶子节点开始调整
        for(int i=(a.length/2-1);i>-1;i--){
            adjustHeap(a,i,n);
        }
        //交换元素并继续调整,从根节点开始调整
        for(int i=n-1;i>-1;i--){
            int tmp = a[i];
            a[i] = a[0];
            a[0] = tmp;
            adjustHeap(a,0,i);
        }

    }
    //对某一个父节点进行调整
    public static void adjustHeap(int[] a, int parent, int length){
        int temp = a[parent];
        int child = parent*2+1;//从左子节点开始

        while(child < length-1){
            //判断是否存在右子叶子节点,并将大的赋值给child
            if(child+1<length && a[child]<a[child+1]){
                child++;
            }
            //判断父节点是否比子节点大,若大于则说明当前父节点无需接着进行调整
            if(temp > a[child])
                break;
            //否则交换父节点和子节点
            a[parent] = a[child];

            //因上面的调整影响到下面节点,所以接着进行调整
            parent = child;
            child = parent *2+1;
        }
        a[parent] = temp;   
        }
}

总结:
选择排序的基本思想就是每次都选择出当前最大或者最小的元素直接放到相应的位置上。

十大排序算法详解(一)冒泡排序、选择排序、插入排序、快速排序、希尔排序 冒泡排序、选择排序、插入排序、快速排序、希尔排序 阅读详情

相关推荐

漫谈经典排序算法:一、从简单选择排序到堆排序的深度解析

1、序言 这是《漫谈经典排序算法系列》第一篇,该篇从最简单的选择排序算法谈起,由浅入深的详细解析两种选择排序算法的过程及性能比较。逐步揭露选择排序的本质及其基本思想。 各种排序算法的解析请参考如下: 《漫谈经典排序算法:一、从简单选择排序到堆排序的深度解析》 《漫谈经典排序算法:二、各种插入排序解析及性能比较》 《漫谈经典排序算法:三、冒泡排序 && 快速排序》 《漫谈经典排序算

Touch_2011的专栏 3万+

【数据结构】堆、二叉堆(java实现)

1.堆是一种完全二叉树: 2.在堆中有两个重要的公式: 已知parent下标,left=2*parent+1 right=2*parent+2 已知child的下标(不分左右) parent=(child-1)/2; 3.堆 1)逻辑上是一种完全二叉树 2)物理上是一个数组 4.满足任意位置的值>=它的左右孩子的值 大堆 反之 ...

qq_43669007的博客 358

Python选择排序算法(一)

选择排序算法简单理解为:遍历一个数组,从索引为0开始和后面的索引的值对比,找到最小的,和其掉换位置,以此类推。 代码展示: # coding:utf-8 import random # Get min value function def get_min(arg): result = arg[0] for i in range(len(arg)): if...

普天&同庆 5943

《数据结构》堆排序算法

end > 0;end--) {// 将最大值移到末尾// 调整剩余部分end > 0;end--)这是一个倒序循环,从数组的最后一个元素开始,逐步向前移动,直到第一个元素。这是为了将堆顶的最大元素(即数组的第一个元素)逐渐移动到当前“未排序”的数组末尾位置。交换堆顶元素(数组的第一个元素,最大值)和当前“未排序”部分的最后一个元素。这将最大值移到已排序部分的末尾。调整堆的剩余部分。交换后,堆的性质可能被破坏,需要通过AdjustDown函数来重新调整剩余部分以维持最大堆的性质。

2302_79865304的博客 775

【排序算法(一)】选择排序及其改进

选择排序是一种原地排序算法。适用于小文件。由于选择操作是基于键值的交换在需要时才执行,所以选择排序常用于数值较大和键值较小的文件。 优点 容易实现 原地排序(不需要额外的存储空间) 缺点 扩展性较差 :O(N2N^2N2) 算法 寻找未排序序列中的最小值 用当前位置交换最小值 堆所有元素重复上述过程,直到整个序列排序完成 Java版本实现 public voi...

无意呢的博客 1511

CANoe信号波形分析保姆级教程:Graphic窗口从配置到实战避坑

本文详细解析了CANoe的Graphic窗口在信号波形分析中的高效配置与实战应用技巧。从信号显示模式选择、测量光标进阶操作到信号分组策略,提供工程化解决方案,帮助工程师快速定位总线信号异常,提升汽车电子开发与测试效率。

weixin_29279047的博客 265

堆排序算法实现与总结(Java)

堆排序算法 堆排序基本思想 将待排序序列构造成一个大顶堆 排序后,整个序列的最大值就是堆顶的根节点。 将堆顶元素其与末尾元素进行交换,此时末尾元素就为最大值。 然后将剩余 n - 1 个元素重新构造成一个大顶堆,这样会得到 n 个元素的次小值。如此反复执行,便能得到一个有序序列了 堆排序步骤图解 要求,给定数组{4,6,8,5,9},使用堆排序方法,升序排列 步骤一:构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。 1.假设无序序列原始结构如下: 2.此时我们从最后一

微若尘埃璨若星辰的博客 222

实战篇(一):从零构建领域知识图谱——基于Protege的本体建模与知识表示

本文详细介绍了如何从零构建领域知识图谱,重点讲解了基于Protege的本体建模与知识表示方法。通过游戏和电影领域的实战案例,展示了类层次结构设计、属性关系定义、推理验证等关键步骤,帮助读者掌握知识图谱构建的核心技术。

weixin_42613501的博客 481

堆排序算法

整体思想: 从第一个非叶子节点开始将数组初始化为一个大顶堆 大顶堆上第一个元素为最大元素,即数组0号位元素,将该元素放到数组末位上 重新调整大顶堆 继续将数组0号位元素放到倒数第二位置上 注意:如果是从大到小排序,则应该使用小顶堆。 代码实现重点: 调整大顶堆的函数应该传入三个参数,数组,调整起始点,数组长度。 将起始点的值保留,将其赋给子节点(如果子节点大于父节点) 定义指针k指向该节点的左子节点以及左孙子节点等,如果右子节点大于左子节点,则指向右子节点 如果子节点的值大于初始节点的值.

TaoTop1的博客 284

D触发器版图设计的艺术:最小化面积与最大化性能的平衡之道

本文探讨了D触发器版图设计中如何平衡最小化面积与最大化性能的核心挑战。通过分析晶体管布局、互联优化、时钟分布等关键策略,结合先进制程下的功耗与信号完整性考量,为数字IC工程师提供了从基础优化到制造验证的实用解决方案,助力实现高性能、低面积的芯片设计。

aa123的博客 909

要理解成本中心与利润中心的根本区别与适用场景,需从 “责任范围、考核核心、管理目标” 三个核心维度切入,同时明确二者在企业管理体系中的联动关系

摘要: 成本中心与利润核心区别在于责任范围、考核目标和管理权限。成本中心仅对成本负责(如生产、行政部门),考核成本控制能力;利润中心需同时管控成本与收入(如独立产品线、区域分公司),以利润为核心指标。选择标准取决于单元是否拥有收入决策权:无收入权的支持/执行部门设为成本中心,能独立经营、核算盈亏的单元设为利润中心。二者协同运作,成本中心为利润中心提供基础支持,利润中心的需求动态影响成本中心资源配置,共同实现企业整体目标。划分本质是确保考核指标与责任范围匹配,避免管理失效。

金牌架构师 656

【排序算法(一)】——插入排序,选择排序 —> 深层解析

排序。

LH__1314的博客 4696

在Simulink中构建感应电机的时滞补偿控制模型,并通过仿真验证不同补偿策略的有效性

核心优势Smith预估器可有效补偿已知时滞,提升系统稳定性。动态PID调整适用于时变时滞的初步补偿。扩展方向自适应时滞估计:结合Luenberger观测器实时估计时滞。鲁棒控制:引入H∞控制或滑模控制抑制参数不确定性。网络化时滞补偿:结合知识库[2]的网络延迟模型,实现端到端补偿。

amy_mhd的博客 189

排序算法(一)选择排序

选择排序 选择排序的概念 选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。 选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们...

lrhaoya 334

innovus:addRepeaterByRule用法

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?addRepeaterByRule不管transition/timing violation,只根据约束的length/cap/fanout等等去给net 插buffer。

m0_61544122的博客 1089

YOLOv8源码解析与复现:ShuffleAttention:高效的混合注意力机制 实现通道和空间混合注意力

随着深度学习在计算机视觉领域的飞速发展,卷积神经网络(CNNs)已经成为图像分类、目标检测、语义分割等任务的核心。为了进一步提升模型的性能,研究者们引入了“注意力机制”,旨在让网络能够动态地关注输入数据中最具信息量的部分。经典的注意力模块,如SE-Net(Squeeze-and-Excitation Networks)和CBAM(Convolutional Block Attention Module),通过通道注意力或结合通道与空间注意力,显著增强了模型的特征表达能力。

FJN110的博客 554

C#排序算法一 选择排序

#region 选择排序 //经典排序方法 //说明排序的思路 /// <summary> /// 双重循环,外循环遍历一遍数据,内循环控制对比次数 /// 每次内循环就可以找出当前位置上最小的一个值 /// </summary> /// <param name="a"></param> protected static void .

weixin_43941291的博客 1121

四舵轮底盘运动学模型(源码)(四轮四独立转向)二

舵轮4转向活动范围 x 轴正半轴,x轴正方向为0弧度,左正右负, -M_PI/2 < 转向范围 < M_PI/2;移动底盘的正前方为x方向,左侧为y轴方向(遵循右手坐标系,右手大拇指指向天空为z轴方向,食指与中指垂直,食指指向小车正前方为x轴,中指指向为移动底盘y轴方向)转向:逆时针旋转角速度w为正,顺时针旋转角速度w为负。(遵循右手螺旋法则,右手握拳大拇指指向天空为旋转z轴方向,拳垂直于地面,4指方向即底盘转动的正方向)左前轮为1号轮,右前轮为2号轮,左后轮为3号轮,右后轮为4号轮。

苏凯的博客 527

一张图精通多种排序算法的选择策略

排序算法是计算机科学中的基石,广泛应用于数据处理、搜索优化和日常业务逻辑中。冒泡排序以其简单性适用于教学和小数据集;选择排序则因其稳定性而受到青睐;插入排序效率高于几乎有序的数据。希尔排序通过优化插入排序提升性能,适用于中等规模数据集。归并排序以其稳定的时间复杂度和稳定性,成为合并操作的首选。快速排序以其分治策略和高效性成为处理大数据集的优选。堆排序则因其原地排序特性而广泛应用于资源受限环境。计数排序和基数排序专为特定数据范围设计,提供线性时间复杂度的解决方案。桶排序则适用于处理均匀分布的大数据集。这些算法

肖哥弹架构博客 1275

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

排序算法代码实现(一)—— 选择排序

以下几篇随笔都是记录的我实现八大排序的代码,主要是贴出代码吧,讲解什么的都没有,主要是为了方便我自己复习,哈哈,如果看不明白,也不要说我坑哦! 本片分为两部分代码: 常用方法封装 排序算法里需要频繁使用 交换数组中两数位置 的操作,另外,为了方便我打印数组查看结果,我封装一个 ArrayBase.java基类,用来实现swap方法和printArray方...

CherishTheYouth的博客 1045

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

选择排序算法流程图_排序算法系列之选择排序(一)

写在前面十大排序算法一直以来都是面试考擦的重点,本文将以简单、易懂的文字来讲清楚十大排序算法之一的选择排序。下面我将从原理、代码、优化、复杂度分析、稳定性分析和应用场景这几个方面来剖析选择排序,读者朋友一看就懂,一写就会。基本原理选择排序突出“选择”二字,实际上就是从待排序数据中“选择”出符合条件的元素按顺序放到序列头部。官方定义是这样的:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存...

weixin_39540744的博客 644

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

排序算法一:选择排序

最简单也最没用的一种算法,时间复杂度为O(n²),而且不稳定,工程中一般不用… 思想:指定一个当前最小数(一般选第一个数),记录其下标为minpos,将它与后面的每一个数依次比较,若有数小于当前最小数,则交换两者的下标,并交换两个数的位置,重复上述步骤直到排好序 平均时间复杂度:O(n²),空间复杂度:1,不稳定 public class Test { public static v...

少年Dream 204

排序算法(一)选择排序算法

排序算法(一)选择排序算法 先开个篇,过几天补上,嘿嘿。

weixin_39765687的博客 166

十大经典排序算法详解(一)冒泡排序,选择排序,插入排序

目录1.算法的评判标准2.2.十大经典排序算法2.1-冒泡排序2.2-选择排序2.3-插入排序2.4-希尔排序2.5-归并排序2.6-快速排序2.7-堆排序2.8-计数排序2.9-桶排序2.10-基数排序 1.算法的评判标准 在讲解排序算法之前,我们首先来了解一下评判一个算法一般都是从哪些角度来评判的.其次 2. 2.十大经典排序算法 2.1-冒泡排序 算法思想: 说到 示例代码: public static void main(String[] args) { int []num ={7,4,9,3

lovely__RR的博客 3349

排序算法之——选择排序(一)简单选择排序

简介 简单选择排序虽然是选择排序,但它在我眼中却是和冒泡排序的思想极其相似的。它们的差别在于,在for循环中,冒泡排序发现逆序就交换,而简单选择排序是在寻找最小值,到最后再把当前i指向的位置得值和最小值的位置的值进行交换。 步骤 1、利用for循环,让i指向一个位置 2、在i指向的后续位置依次进行比较,寻找到一个最值 代码实现 void SelectSort(RecordType r[],int ...

ganlubaba666的博客 271
上一篇: 牛客之程序员面试金典_ 编程题(二)
下一篇: 排序算法总结(二)——插入排序
小菜鸟要高飞
博客等级 码龄12年 14粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值