【数据结构详解】——选择排序(动图详解)

通俗易懂讲解 [图解]选择排序 文章目录1.选择排序2. 图示过程3.动图展示4.约定5.过程6.代码 1.选择排序 从数组中选择最小元素,将它与数组的第一个元素交换位置。再从数组剩下的元素中选择出最小的元素,将它与数组的第二个元素交换位置。不断进行这样的操作,直到将整个数组排序。 选择排序需要 ~N2/2 次比较和 ~N 次交换,它的运行时间与输入无关,这个特点使得它对一个已经排序的数组也需要这么多的比较和交换操作。 2. 图示过程 3.动图展示 4.约定 待排序的元素需要实现 Java 的 Comparable 接口,该接口有 c 阅读详情

🕒 1. 直接选择排序

💡 算法思想:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始(末尾)位置,然后选出次小(或次大)的一个元素,存放在最大(最小)元素的下一个位置,重复这样的步骤直到全部待排序的数据元素排完。
请添加图片描述

代码实现如下:这里可以进行一个优化,最小值和最大值同时选,然后将最小值与起始位置交换,将最大值与末尾位置交换。

void Swap(int* p1, int* p2)
{
    int tmp = *p1;
    *p1 = *p2;
    *p2 = tmp;
}

void SelectSort(int* a, int n)
{
    int begin = 0;  // 起始位置
    int end = n - 1;  // 结束位置

    // 循环直到整个数组都被排序
    while (begin < end)
    {
        int mini = begin;  // 保存最小元素下标
        int maxi = begin;  // 保存最大元素下标

        // 在当前未排序部分查找最小和最大元素的下标
        for (int i = begin + 1; i <= end; ++i)
        {
            if (a[i] < a[mini])
            {
                mini = i;  // 更新最小元素下标
            }
            if (a[i] > a[maxi])
            {
                maxi = i;  // 更新最大元素下标
            }
        }

        // 将找到的最小元素交换到起始位置
        Swap(&a[begin], &a[mini]);

        // 如果最大元素的位置在起始位置,更新最大元素下标为 mini
        if (maxi == begin)
        {
            maxi = mini;
        }

        // 将找到的最大元素交换到末尾位置
        Swap(&a[end], &a[maxi]);

        // 缩小排序范围
        ++begin;
        --end;
    }
}

在这里插入图片描述

选择排序的特性总结:

  1. 选择排序步骤非常好理解,但是效率不是很好(不论数组是否有序都会执行原步骤),实际中很少使用。
  2. 时间复杂度:O(N2)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定

🕒 2. 堆排序

💡 算法思想:堆排序即利用堆的思想来进行排序,总共分为两个步骤:1. 建堆(升序:建大堆;降序:建小堆) 2. 利用堆删除思想来进行排序:建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。

这里以升序为例:

  • 首先应该建一个大堆,不能直接使用堆来实现。可以将需要排序的数组看作是一个堆,但需要将数组结构变成堆结构。
  • 我们可以从堆从下往上的第二行最右边开始依次向下调整直到调整到堆顶,这样就可以将数组调整成一个堆,且如果建立的是大堆,堆顶元素为最大值。
  • 然后按照堆删的思想将堆顶和堆底的数据交换,但不同的是这里不删除最后一个元素。
  • 这样最大元素就在最后一个位置,然后从堆顶向下调整到倒数第二个元素,这样次大的元素就在堆顶,重复上述步骤直到只剩堆顶时停止。

请添加图片描述

// AdjustDown函数:在数组a中,从节点root开始向下调整,使得以root为根的子树满足大顶堆的性质。
void AdjustDown(int* a, int n, int root)
{
	assert(a);
	int parent = root; // 当前子树的根节点
	int child = parent * 2 + 1; // 左孩子节点

	// 循环直到没有孩子节点
	while (child < n)
	{
		// 如果右孩子存在且比左孩子大,则选择右孩子作为比较对象
		if (child + 1 < n && a[child + 1] > a[child])
		{
			child++;
		}

		// 如果孩子节点比父节点大,则交换父节点和孩子节点的值,并更新父节点和孩子节点继续向下比较
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break; // 如果孩子节点不再比父节点大,则退出循环
		}
	}
}

void HeapSort(int* a, int n)
{
	assert(a);
 
	// 建立大顶堆
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, n, i); // 对每个非叶子节点进行向下调整,建立大顶堆
	}
 
	// 交换堆顶元素和末尾元素,并重新调整堆
	for (int i = n - 1; i > 0; i--)
	{
		Swap(&a[i], &a[0]); // 将当前堆顶(最大值)与数组末尾元素交换
		AdjustDown(a, i, 0); // 调整剩余堆为大顶堆,范围缩小为0到i-1
	}
}

在这里插入图片描述

堆排序的特性总结:

  1. 堆排序使用堆来选数,效率较高,适用于需要频繁插入和删除的场景。
  2. 时间复杂度:O(N*logN)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定

❗ 转载请注明出处
作者:HinsCoder
博客链接:🔎 作者博客主页

选择排序算法(内置动图) 关于选择排序的思路、代码、图解超详细介绍 阅读详情

相关推荐

用Python实现十大经典排序算法(附动图)

快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 O(nlogn) 的时间复杂度。

zzjlhlcd的博客 1022

排序算法-选择排序(可视化动图)

选择排序 最简单,也是最没用的排序算法,没用是因为选择排序的时间复杂度高并且还是不稳定的排序方法,项目中很少会用到 算法介绍 在一个长度为 N 的无序数组中,第一次遍历 n-1 个数找到最小的和第一个数交换。 第二次从下一个数开始遍历 n-2个数,找到最小的数和第二个数交换。 重复以上操作直到第 n-1 次遍历最小的数和第 n-1 个数交换,排序完成。 算法可视化 实现代码 算法实现 Selection.java package sort.selection; import sort.utils.So

刘孟棋的博客 3555

十大经典排序算法(动图演示)(***)

十大经典排序算法(动图演示)(***)

ken2232的博客 1217

数据结构七大排序算法图解——选择排序动图演示

详细整理——直接选择排序+树形排序+堆排序(代码+动图演示) ...

二哈喇子! 7740

在游戏开发中如何使用Unity3D引擎开发麻将游戏

总体来说使用Unity3D引擎开发麻将游戏需要开发人员熟练掌握Unity3D的各种功能和API,并且需要深入了解麻将游戏的规则和背景,以便实现一个质量高、玩法丰富的游戏。在测试的过程中我们需要检查游戏是否符合规则,保证游戏逻辑的正确性,并检查游戏的UI是否和设计图一致,保证游戏的可玩性。Unity3D引擎是一个高度集成的游戏开发工具,可以为开发人员提供很多强大的工具和功能,包括3D建模、物理模拟、粒子系统、动画等等,在游戏开发中可以提高开发效率和游戏质量。在开始开发之前我们需要明确游戏的需求和功能。

a272857154的专栏 1889

基于 WebGoat 平台的 SQL 注入攻击

基于 WebGoat 平台的 SQL 注入攻击

Labulongdong的博客 3522

排序算法时间复杂度、空间复杂度、稳定性比较

排序算法分类排序算法比较表格填空 排序算法 平均时间复杂度 最坏时间复杂度 空间复杂度 是否稳定 冒泡排序 :————-: :—–: :—–: :—–: 选择排序 :————-: :—–: :—–: :—–: 直接插入排序 :————-: :—–: :—–: :—–: 归并排序 :————-: :—–: :

小黑皮的技术博客 11万+

一文告诉你:如何在trae中编译运行STM32程序,并让AI帮你修改代码

本文详细介绍了如何将STM32程序从Keil迁移到国产免费工具Trae,并利用AI进行代码修改的全过程。

水滴爬呀爬 4883

数据结构排序算法详解(2)——选择排序(附动图)

本文聚焦选择排序体系展开解析,涵盖直接选择排序、堆排序,及与插入排序的对比。 首先介绍直接选择排序的概念与实现,说明其时间复杂度为O(n²),并梳理其核心特性;继而讲解堆排序的概念及基于堆结构的实现逻辑,指出其时间复杂度稳定为O(nlogn)、空间复杂度O(1),还提及可用于Top-K问题(效率达O(n+klogn)),同时总结其特性。 文章还对比了插入排序与选择排序的差异,附总代码示例辅助实操理解。 全文以清晰的层级,为选择排序的学习、应用提供了实用指引。

梦是现实的延续,现实是梦的结束。 1282

学习C++的递归函数(包含汉诺塔讲解)

简单来讲,递归函数就是函数本身自己调用自己,那么函数又是什么呢?#include <stdio.h> //这行是头文件,不同的头文件可以用不同的函数int main() //这里就是一个main函数//这里是你要编写程序的内容return 0;(这是个小细节如下)所以我们平时用来练习的就是一个main函数,而且是一个整型类型的函数,而这也是最后一句话为什么要加一句 return 0;了,因为它最后要返回整数类型,其它整数也可以,但是大家规定为0,这是C++自带的函数。

2302_81032013的博客 2594

【连接器专题】 EIA-364 系列标准的完整列表

EIA-364 系列标准在电子工业中具有重要的地位,为电子连接器和互连系统的测试和验证提供了统一的、可操作的流程和方法,有助于提高电子产品的质量和可靠性,促进了电子工业的发展

一点硬件 2658

【C语言】-- 数据结构 -- 选择排序类(简单选择排序,堆排序)(超详解+动图+源码)

包括时间复杂度,空间复杂度,稳定性(带图讲解)

weixin_64609308的博客 1149

【四足机器人项目实战】四足机器人支撑腿反作用力规划之VMC解耦控制方法

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、基于模型的工作空间控制框图二、原理三、缺点 前言 认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长! 本文先对未简化的动力学模型规划反作用力+运动学模型雅可比+虚功原理规划关节扭矩方法做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章 提示:以下是本篇文章正文内容 一、基于模型的工作空间控制框图 . . 二、原理 基于机器人的动力学模

qq_35635374的博客 6597

动态图文超详解十大排序算法

超级详细动图详解十大排序算法 https://www.jianshu.com/p/47170b1ced23

bad_boy的博客 232

RH850从0搭建Autosar开发环境【1】- 如何创建Davinci Configurator配置工程

当我们在公司接触Autosar开发环境时,基本都是完整的Davinci Configurator的配置工程,我们只能修修补补。 从本章开始将手把手搭建Rh850基于Vector公司Davinci Configurator的autosar配置工程。主要涉及到OS,COM,DCMM,NVM,BSWM,ECUM等基本模块,包括Vlink,memap使用,XCP标定的实现等。基本是实现一个基础版的项目开发。包括后期的GreenHills编译问题处理,生成最终的Hex文件。

weixin_42412049的博客 1万+

【Codex】Codex安装+DeepSeek API接入;无需登录,手把手带你使用codex

好多人使用codex时都卡在验证码登录那一步,今天就来介绍一种方法,不需要登录ChatGPT的账号,自然也就不需要手机验证码了;接入DeepSeek的api,一样可以丝滑使用codex;记录从零开始安装使用codex以及DeepSeek API接入的整个过程。不需要登录openAI;

AnChenliang_1002的博客 3535

【数据结构】常见八大排序算法(附动图)

本文围绕八种常见排序算法展开讲解,包含算法思想、动图、源代码和对算法的优化等

Eristic0618的博客 9993

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【数据结构详解】——归并排序(动图详解)

💡 算法思想:归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用**分治法**的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列。即先使每个子序列有序,再使子序列段间有序,若将两个有序表合并成一个有序表,称为**二路归并**。

HinsCoder的博客 1万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【java】十大经典排序算法(动图演示)

十大经典排序算法(动图演示) 0,算法概述 0.1算法分类 十种常见排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序。 线性时间非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此称为线性时间非比较类排序。  0.2算法复杂度 ...

csdn_baotai的博客 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

排序算法-选择排序(选择排序、堆排序)(动图演示)

我们找到了最后一个非叶子节点,即元素值为6的节点,

2401_83177222的博客 1318

数据结构-八大排序详解(动图+实现详解+总结)

数据结构-八大排序详解(动图+实现详解+总结)

吴名氏的博客 4万+

【数据结构】排序算法---直接选择排序(动图演示)

直接选择排序的详解,还包含动图助解

2301_80191662的博客 1919

Java选择排序

1. 选择排序 选择排序是一种简单直观的排序算法,其基本原理是每一次从待排序的数组里找到最小值(最大值)的下标,然后将最小值(最大值)跟待排序数组的第一个进行交换,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。反复的进行这样的过程直到待排序的数组全部有序。 2.选择排序的动图 相信通过这个动图,您已经明白,选择排序是怎样的原理吧!接下来用Java来实现选择排序。 代码如下: public class selectSort { public static void ma

木有君兮的博客 1万+

经典四大排序(动图实现)

这个大佬整理的很仔细: https://blog.youkuaiyun.com/m0_37741420/article/details/106981276?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162777450716780262565601%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=162777450716780262565601

Myblog 2万+

【数据结构】——十大排序详解分析及对比

排序算法是《数据结构》中最基本的算法之一我们先来大致简单了解一下排序算法吧排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存根据排序的特点可以将排序分为:直接插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序等

2302_78420373的博客 2707

数据结构七大排序算法图解——插入排序动图展示

插入排序动图演示——直接插入排序、希尔排序

二哈喇子! 5332
上一篇: 【数据结构详解】——插入排序(动图详解)
下一篇: 【数据结构详解】——冒泡排序(动图详解)
HinsCoder
博客等级 码龄5年 1万+粉丝 220原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值