详解排序算法(三)之2种选择排序(简单选择排序、堆排序)

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

简单选择排序

算法步骤

  1. 遍历数列,找到最小的值,置于第1位
  2. 从第2位开始,遍历数列,找到最小的值,置于第2位
  3. 以此类推,直到开始位置变为最后一位,排序结束。

示例

我们取 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48 来进行示范

  1. 第1轮排序,从第1位 3 开始,遍历数列,找到最小值 2,将其置于第1位,即与 3 交换位置,得 2, 44, 38, 5, 47, 15, 36, 26, 27, 3, 46, 4, 19, 50, 48

  2. 第2轮排序,从第2位 44 开始,遍历数列,找到最小值 3,将其置于第2位,即与 44 交换位置,得 2, 3, 38, 5, 47, 15, 36, 26, 27, 44, 46, 4, 19, 50, 48

  3. 第3轮排序,从第3位 38 开始,遍历数列,找到最小值 4,将其置于第3位,即与 38 交换位置,得 2, 3, 4, 5, 47, 15, 36, 26, 27, 44, 46, 38, 19, 50, 48

  4. 以此类推,直到开始位置变为最后一位,排序结束。

动态图
img

javascript代码

function selectionSort (arr) {
    let min, temp

    for (let i = 0; i < arr.length - 1; i++) {
        min = i // 最小数索引
    
        for (let j = i; j < arr.length; j++) {
            if (arr[j] < arr[min]) {
                min = j
            }
        }

        temp = arr[i]
        arr[i] = arr[min]
        arr[min] = temp
    }

    return arr
}

堆排序

在讲堆排序之前,我们先了解一些二叉树的知识。

  1. 二叉树

    简单地理解,满足以下两个条件的树就是二叉树:

    • 本身是有序树;

    • 树中包含的各个节点的度不能超过 2,即只能是 0、1 或者 2;

    二叉树示意图

  2. 满二叉树

    如果二叉树中除了叶子结点,每个结点的度都为 2,则此二叉树称为满二叉树。

    满二叉树示意图

  3. 完全二叉树

    如果二叉树中除去最后一层节点为满二叉树,且最后一层的结点依次从左到右分布,则此二叉树被称为完全二叉树。

完全二叉树示意图

​

​ 对于完全二叉树来说,如果记根节点的索引值为0,那么对于任意一个节点i,其左右节点如果存在的话,索引值分别为 2i + 1,2i + 2。之所以介绍二叉树,是因为堆排序就要用到我们上面所讲的完全二叉树。

算法步骤

  1. 建立大跟堆或小跟堆,我们以大根堆为例,所谓建立大跟堆,就是各个节点与其左右节点比较,将大的值置换到根部,这样一个个节点比较下去,直到将最大的值置换到根节点,大跟堆建立完毕。

  2. 将大根堆中的根节点与其尾节点进行交换

  3. 将二叉树的长度减一,即尾结点不参与下一轮排序。重复操作1,直到直到堆的尺寸为 1。

示例

我们取 91, 60, 96, 13, 35, 65, 46, 65, 10, 30, 20, 31, 77, 81, 22 进行示范。

数列对应的完全二叉树如下图

image-20220309152552974

第一轮排序

  1. 46 与 81、22 比较,81最大,81 与 46 互换位置,得
    image-20220309152931614

  2. 65 与 31、77 比较,77最大,77 与 65 互换位置,得
    image-20220309153200342

  3. 35 与 30、20 比较,35最大,位置不变。

  4. 13 与 65、10 比较,65最大,65 与 13 互换,得
    image-20220309153734642

  5. 96 与 77、81 比较,96最大,位置不变

  6. 60 与 65、35比较,65最大,65 与 60 互换,得
    image-20220309154706189

  7. 91 与 65、96比较,96最大,96 与 91互换,得到最大值96
    image-20220309154753237

  8. 将根节点96与尾结点22互换,即最大值置于尾结点。数列长度减一,即尾节点不再参与堆构建,如图
    image-20220309154904473

  9. 第一轮排序结束,重复以上步骤,直到堆的尺寸为 1,排序结束。

动态图
img

javascript代码

let last // 参与堆构建的最后一个节点索引值

// 建立大根堆
function buildMaxHeap(arr) {
    for (let i = Math.floor((last + 1) / 2); i >= 0; i--) {
        heapify(arr, i)
    }
}

// 堆调整函数,此处为构建大根堆
function heapify (arr, i) {
    // 在完全二叉树中,索引值从0开始,若节点i存在左右子节点,则左右子节点索引分别为 2i + 1, 2i + 2
    let left = 2 * i + 1,
        right = 2 * i + 2,
        largest = i

    if (left <= last && arr[left] > arr[largest]) {
        largest = left
    }

    if (right <= last && arr[right] > arr[largest]) {
        largest = right
    }

    if (largest != i) {
        swap(arr, i, largest)
    }
}

function swap(arr, i, j) {
    let temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

// 堆排序
function heapSort(arr) {
    for (let i = 0; i < arr.length - 1; i++) {
        last = arr.length - 1 - i
        buildMaxHeap(arr)
        swap(arr, 0, last)
    }

    return arr
}

两种算法的复杂度及稳定性

排序算法时间复杂度(平均)时间复杂度(最坏)时间复杂度(最好)空间复杂度稳定性
简单选择排序O(n2)O(n2)O(n2)O(1)不稳定
堆排序O(nlog2n)O(nlog2n)O(nlog2n)O(1)不稳定
排序算法:冒泡、简单选择、直接插入、归并、堆排序、快速排序 简单的三种排序 总结:排序算法中最基本的三种算法(简单选择,冒泡,插入),这三种排序算法的时间复杂度均为O(n2) 性能总结: 1、稳定性:归并排序最好。 2、空间复杂度:堆排序最好。 3、经过优化的快速排序最好,普通快速排序像是情绪化的天才。 引出原因: 1、归并排序:堆排序结构复杂,直接利用完全二叉树。1.分解:将当前区间一分为二,即求分裂点2.求解:递归地对两个子... 阅读详情

相关推荐

手把手教你用RTL8306MB搭建小型网络交换机:从原理到实战

本文详细介绍了如何使用RTL8306MB交换芯片从零搭建小型网络交换机的全过程。内容涵盖芯片原理分析、核心硬件电路设计(包括电源、时钟、RMII接口连接要点)、驱动开发与SMI通信实现,以及从物理链路到交换功能的系统调试实战。重点解析了将MAC5配置为RMII PHY模式与CPU对接的关键步骤和常见错误,帮助嵌入式开发者深入理解网络交换原理并完成实践。

weixin_29274969的博客 192

两种选择排序的实现

简单选择排序 从数组的第一个元素开始遍历,将当前遍历的元素与后面的元素依次比较,记录下最小数的下标,每次循环将最小数移动到最前面。外循环结束,数组则有序。 实现代码: public static void selectSort(int arr[]){ for(int i=0;i<arr.length-1;i++){ int min=i; ...

Hsiao99的博客 309

对于基本的捕鱼游戏设计思路(五)——鱼

今天讲捕鱼游戏里鱼的部分,也是比较关键的一部分。 一步一步来,先分析游戏,首先鱼是从屏幕外生成,然后它有个移动的动作,而且分为不同的类型。 然后就可以进入代码部分,首先设置一个计时器,控制时间生成鱼,而鱼分种类,所以就用到随机函数,随机输出一个值,传入switch语句,从而生成不同的鱼。 void GameScene::xiaoyuupdate(float dt){ Size visibl

Cineze的博客 1万+

选择法排序的两种方法

#include &amp;amp;amp;amp;amp;amp;amp;lt;stdio.h&amp;amp;amp;amp;amp;amp;amp;gt; /* 选择法排序的两种方法 选择法算法:将最小的数与第一个对换,这样最小的数就排在最前面;然后将第二小的数与第二个对换…如此, 经过n-1轮后,排序成功。 a[0] a[1] a[3] a[4] a[5] 3  6  1  9  4 //未排序之前 1  6  3  9  4 //第一轮 1  3  6

sammwang的博客 2279

手把手教你用GD32F407VET6的EXMC驱动外部SRAM,搞定大内存需求

本文详细介绍了如何使用GD32F407VET6的EXMC外设驱动外部SRAM,解决嵌入式开发中的大内存需求问题。通过硬件连接方案、EXMC时序配置与初始化步骤,以及软件集成与内存管理技巧,帮助开发者快速实现内存扩展。特别适合需要处理图形显示缓冲、音频处理等大内存场景的GD32F407开发者。

weixin_30752699的博客 347

(数字图像处理MATLAB+Python)第五章图像增强-第一节:图像增强概述和基于灰度级变换的图像增强

图像增强(Image Enhancement):指不考虑图像降质原因,利用各种数学方法和变换手段,增强图像中人们感兴趣部分或提高有用的图像特征的清晰度。从图像质量来看,图像增强提高了图像的可懂度,改善了图像的视觉效果例如在现实场景中,针对那些对比度较差、视觉效果不好的图像,我们就可以利用图像增强改善视觉质量图像增强可分为如下几种基于灰度级变换的图像增强基于直方图修正的图像增强基于照度反射模型的图像增强基于模糊技术的图像增强基于伪彩色处理的图像增强其他图像增强方法分段线性灰度级变换。

快乐江湖的博客 3334

排序算法——堆排序

8.堆排序 (1)介绍 ① 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最好、最坏、平均时间复杂度均为O(nlogn),不是稳定排序; ② 堆排序是利用了顺序存储二叉树的思想; ③ 堆是具有以下性质的完全二叉树:每个结点的值都大于或者等于它的左子结点和右子结点,称之为大顶堆;每个结点的值都小于或者等于它的左子结点和右子结点,称之为小顶堆; ④ 升序使用大顶堆,降序使用小顶堆。 (2)基本思想 ① 首先要根据题上的要求,将待排的无序序列调整成为大顶堆或者小顶堆,以下

weixin_53754024的博客 569

利用XGBoost实现短期电力负荷预测

本数据集为某地区2009年-2015年的用电负荷,时间片为每分钟这里我们定义了XGB模型作为实例,来进行模型训练,之后我们会对其使用网格搜索找到最优的参数。

优快云 精品推荐 4496

经典算法_数组

1 对一个一维数组进行按照元素的升序大小进行排序,冒泡排序法 2 随机生成一个有10个元素的一维数组,并找出极值 3 将一个一维数组中n个整数按相反顺序存放 4 用指针方法对10个整数按照从大到小顺序排序,冒泡排序法 5 用随机数生成一个数组,写一个函数查找最小的,并返回最小数的地址。在主函数中打印出来最小数 6 不改变原有的一维数组排序,使用指针数组,进行排序,冒泡排序...

B1334628598的博客 3317

具身大小脑全栈全网独家复现|LLM链式推理+边缘VLA感知+毫秒级运动小脑、优化人形步态僵硬运动滞后、打通思考-行走-操作全链路适配居家工业多场景落地

高层决策大脑(异步10Hz,GPU算力):轻量化机器人微调LLM+RhinoVLA边缘视觉大模型,负责自然语言链式工序拆解、全局环境语义感知、目标物体筛选、跨机器人动作适配,输出粗粒度运动目标,不介入底层伺服计算;依托View Registry实现异构机器人动作对齐,适配多形态机器人切换;中层调度小脑(硬实时1kHz,CPU算力)

qq_36130719的博客 257

【06】C#入门到精通——C# 多个 .cs文件项目 同一项目下添加多个 .cs文件

本文介绍了如何将C#游戏开发中的代码从单个.cs文件拆分到多个.cs文件中,以提升代码的可维护性和可读性。文章演示了在Visual Studio中创建Hero类和ShowInfo类的具体步骤:通过右键项目名添加新建类,将原有代码分别剪切到对应的类文件中,并自动生成命名空间。拆分后需要在Program.cs中通过"using"指令引用这些类,最后通过运行测试验证功能正常。这种模块化代码组织方式能有效解决单一文件代码过长、结构混乱的问题。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 1138

C语言筛选法求素数

素数的定义:素数也即质数;在大于1的自然数中,除了1和他本身以外没有其他的因数,我们称之为素数。 问题:求出1-100之内的素数。 方法1,利用定义直接遍历 #include<stdio.h> #include<math.h> //思路:优化了j的范围而非(2-i)因为如果一个数不能被从2到其开方的数整除,其即为素数 //时间复杂度:nlog2n void main()...

林立可 9427

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

【排序算法】选择排序、堆排序

堆排序是一种基于堆(Heap)数据结构的排序算法。最大堆:每个节点的值都大于或等于其子节点的值。根节点是最大值。最小堆:每个节点的值都小于或等于其子节点的值。根节点是最小值。首先将无序数组构建为一个最大堆。然后,将堆顶(即最大值)与数组的最后一个元素交换,缩小堆的范围,对剩下的元素继续调整成最大堆,直到排序完成。

2301_76677973的博客 2940

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

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

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

用C语言进行学生成绩排序(简单选择排序和堆排序)

本文主要是用C语言进行学生成绩排序,包括简单选择排序、堆排序,含源代码。

墨城烟柳ベ旧人殇的博客 5943

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

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

十大经典排序算法-堆排序算法详解

一、什么是堆排序 1.概念 堆排序(Heapsort)是利用二叉堆的概念来排序的选择排序算法,分为两种: 升序排序:利用最大堆进行排序 降序排序:利用最小堆进行排序 2.算法原理 给定一个最大堆如下图所示,以该最大堆进行演示堆排序 首先,删除堆顶元素10(即最大的元素),并将最后的元素3补充到堆顶,删除的元素10,放置于原来最后的元素3的位置 根据二叉堆的自我调整,第二大的元素9会成为二叉堆新的堆顶 删除元素9,元素8成为最大堆堆顶 删除元素8,元素7成为最大堆堆顶 依次删除最大元素,直至所有

qq_35344198的博客 1万+

C++实现选择排序算法(简单选择排序、堆排序)

排序算法分为五大类,一共是有九种,如下: 插入类:直接插入排序、折半插入排序、希尔排序 交换类:冒泡排序、快速排序 选择类:简单选择排序、堆排序 归并类:二路归并排序 基数类:多关键字排序 九种算法的时间复杂度、空间复杂度和稳定性小结如下: 本文放出选择算法的两种排序算法代码。 简单选择排序 void SelectSort(int R[], int n) { int i, j, k, temp; cout << "简单选择排序" << endl; for (i = 0; i

qq_38222051的博客 4364

排序算法上——插入,希尔,选择,堆排序

在希尔排序开始时增量较大,分组较多,每组的记录数目少,n小,此时直接插入最好和最坏时间复杂度n2差距很小,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。2. 然而在排序的时候,时间消耗过于庞大,因为在挪动元素时,会把堆内的序列和关系打乱,因此应该建大堆,然后利用算法进行调整。1.希尔排序的核心在于对数组进行预排序,值得注意的是,预排序只是让数组相对有序,而非达到真正的有序状态。

2303_81060385的博客 1512

堆排序怎么建立初始堆_第二篇,选择排序算法:简单选择排序、堆排序

此为第二篇,选择排序算法:简单选择排序、堆排序。简介选择排序的基本思想是:每一趟(如第i趟)在后面 n-i+1 ( i = 1 , 2, ...., n-1) 个待排序元素中选取关键字最小的元素,作为有序子序列的第i个元素,直到第 n-1 趟做完,待排序元素只剩下一个,就不用再选了。基于选择的排序算法主要介绍简单选择排序和堆排序。一.简单选择排序简单选择排序算法的思想:假...

weixin_31642531的博客 1万+

【排序算法】——选择排序

排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列。所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 排序算法,就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面。一个优秀的算法可以节省大量的资源。

2302_80243065的博客 3309

排序算法 选择排序(简单排序、堆排序)

依次类推,共需要进行的比较次数是(n-1)+(n-2)+…+2+1=n(n-1)/2,即进行比较操作的时间复杂度为O(n^2),进行移动操作的时间复杂度为O(n)。该趟排序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R[i+1..n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;时间复杂度,最佳情况:O(n^2) 最差情况:O(n^2) 平均情况:O(n^2)。------开始------------结束------

qq_36511401的博客 1万+

排序算法之选择排序&堆排序

向下调整:如果父节点比大的孩子小,则两者交换位置,然后进行新一轮比较,直到叶子或 父节点不小于大的孩子。鱿鱼选择排序每次都要扫描一遍数组,时间复杂度O(n)而要进行n次扫描操作,所以时间复杂度为O(n*n)于是把堆顶移除就可以排好一个元素,但是移除应该把堆顶和最后一个交换,否则会严重破坏堆序性,增加复杂度!,需要N次交换+调整,调整复杂度为logn所以时间复杂度为O(NlogN)这应该算是最简单的排序算法了,每次在右边无序区里选最小值,没有无序区时,就宣告排序完毕。

bajia2013的博客 1062

选择排序 ( 直接选择排序 && 堆排序 )

1、直接选择排序 ???? 核心思想 ????   每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。 ❗ 过程:❕   1️⃣ 在元素集合 array[i] - array[n-1] 中选择关键码最大 (小) 的数据元素   2️⃣ 若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换   3️⃣ 在剩余的 array[i] - array[n-2] (array[i+1]–array[n-1]) 集合中,

DanceBit的博客 2万+

常见排序算法之选择排序——直接选择排序、堆排序

哈喽大家好,我是保护小周ღ,本期为大家带来的是常见排序算法中的选择排序,主要有直接选择排序以及——堆排序(有点难理解),包您一看就会,快来试试吧~ ​

保护小周ღ的博客 2341

数据结构-选择排序(简单选择排序,堆排序)

目录 1,简单选择排序 1.1,简单选择排序思想 1.2,选择排序的时间复杂度分析 1.3,简单选择排序代码实现 2,堆排序 2.1,什么是堆排序 2.2,堆排序的思想 2.3,堆排序时间复杂度分析 2.4,代码实现 1,简单选择排序 1.1,简单选择排序思想 选择排序(Selection sort)是一种简单直观的排序算法。 简单选择排序算法的比较次数和初始的序列排列顺序无关。 它的基本思想是:首先在未排序的数列中找到最小(or最大)元素,然后将其存放到数列的起始位置;接着,.

理科男同学 2421

数据结构 | 排序算法——选择排序与堆排序

本文讲解了常见排序算法中的选择排序与堆排序,内附详细算法图解,复杂度分析公式

做技术人 · 产优质博客 · 找好工作 1205
上一篇: 详解排序算法(二)之2种交换排序(冒泡排序、快速排序)
下一篇: 详解排序算法(四)之计数排序
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值