【六大排序详解】中篇 :选择排序 与 堆排序

选择排序 与 堆排序

选择排序

  • 选择排序 与 堆排序
    • 1 选择排序
      • 1.1 选择排序原理
      • 1.2 排序步骤
      • 1.3 代码实现
    • 2 堆排序
      • 2.1 堆排序原理
        • 2.1.1 大堆与小堆
        • 2.1.2 向上调整算法
        • 2.1.3 向下调整算法
      • 2.2 排序步骤
      • 2.3 代码实现
    • 3 时间复杂度分析
  • Thanks♪(・ω・)ノ
    • 下一篇文章见!!!

1 选择排序

1.1 选择排序原理

选择排序可以用扑克牌理解,眼睛看一遍所有牌,选择最小的放在最左边。然后略过刚才排完的那张,继续进行至扑克牌有序。这样一次一次的挑选,思路很顺畅。总结为:
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。
在这里插入图片描述

1.2 排序步骤

  1. 从头开始遍历数组,设置mini指向最小值下标(先指向首元素)。
  2. 遇到比a[mini]小的值,mini改变为新下标。直到遍历到结尾。
  3. 将数组首元素与mini指代元素交换位置。
  4. 从排好序的下一个元素开始,重复 1-3 步骤。
  5. 直到排序完成。
    在这里插入图片描述

1.3 代码实现

void SelectSort(int* a, int n) {int begin = 0;//无序部分开头int mini = 0;//先设置mini指向开头//直到begin = n ,都有序。while (begin<n) {//从无序部分开始,选择最小值。for (int i = begin; i < n; i++) {if (a[i] < a[mini]) //如果小则下标更新。mini = i;}//将选择出来的最小值放置到无序部分开头。swap(a, begin, mini);begin++;//begin向后推进mini = begin;//mini更新}
}

排序功能实现,效果非常棒!
排序结果
直接选择排序的特性总结:

  1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定

2 堆排序

2.1 堆排序原理

堆排序是一种特殊的选择排序,堆排序以二叉树为基础。选择两个子元素其一,然后逐层上升或下沉,直到有序。在认识理解堆排序之前,我们需要了解如何建堆。这里我们由于是学习堆排序,所以下面我只介绍堆的大小堆建立,向上调整算法,向下调整算法。其余堆相关知识会在另一篇文章详细介绍。

2.1.1 大堆与小堆

首先:堆 是一种特殊的树,满足以下条件即为堆,是二叉树的顺序结构。

在这里插入图片描述

二叉树内容见:二叉树解释
根据二叉树的知识,堆一定是完全二叉树(除了最后一层,其他层的节点个数都是满的,最后一层的节点都集中在左部连续位置)
堆分为大小堆
即 :堆中每一个节点的值都必须大于等于或小于等于其左右子节点的值
每个节点的值都大于等于其子树节点的堆叫“大堆“,根是所有数据的最大值
每个节点的值都小于等于其子树节点的堆叫“小堆“,根是所有数据的最小值

2.1.2 向上调整算法

我们如何把基本的数组变成大堆和小堆呢?这里就需要向上调整算法。
向上调整顾名思义,就是从尾部开始,一层一层向上调整。

以建大堆为例

  1. 从尾节点开始,如果该孩子节点大于父母节点,则向上调整(上浮)。
  2. 直到调整到合适的位置。
  3. 尾节点向前推移,继续重复 1 - 2 步骤。
  4. 直到遍历所有元素,完成建堆。
void adjustup(int* a, int child) ;
int main(){
//...for (int i = n - 1; i > 0; i--) {adjustup(a, i);//逐个遍历}
//...
}
//建堆void adjustup(int* a, int child) {int parent = (child - 1) / 2;//根据二叉树知识取父母节点while (child > 0) {if (a[child] > a[parent]) {swap(a, child, parent);//如果该孩子节点大于父母节点,则向上调整(上浮)}child = parent;//孩子节点迭代parent = (child - 1) / 2;//父母节点迭代}}

这样就建立了大堆。小堆原理相同,只需更改大于号和小于号。

2.1.3 向下调整算法

建立好堆之后,如何进行排序呢?这时就需要向下调整算法。首先我们要有一个共识:
排升序建大堆;排倒序建小堆。
之所以这样是因为向下调整算法的缘故,下面我们来看向下调整算法,之后解释原因。
以排升序为例

  1. 首先头元素与尾元素交换位置。
  2. 然后从头开始向下调整,如果父母节点大于孩子节点中较大的,则交换。
  3. 调整完成后,尾向前推进。继续重复 1 - 2 步骤。
  4. 直到遍历所有元素。
void adjustdown(int* a, int parent,int size);
int main(){
//...int end = n - 1;while (end > 0) {swap(a, end, 0);adjustdown(a,0,end);end--;}
//...
}
void adjustdown(int* a, int parent,int size) {int child = parent * 2 + 1;while (child < size) {if (child + 1 < size && a[child + 1] > a[child]) {child++;}if (a[child] > a[parent]) {swap(a, child, parent);}parent = child;child = parent * 2 + 1;}}

这样遍历一遍向下调整就可以完成排序。我们理解向下调整算法之后就可以发现
**排升序建大堆;排倒序建小堆。**是非常巧妙的,
以排升序为例,每次放在交换到首元素 的都是最小值(最大值),然后向下调整,把它放到该放在的位置上。

2.2 排序步骤

我们理解上述两种算法之后,就可以非常顺畅理解堆排序。

  1. 向上调整建堆
  2. 向下调整排序
    在这里插入图片描述
    理解向上调整算法和向下调整算法之后,堆排序就迎刃而解。

2.3 代码实现

void adjustup(int* a, int child) {int parent = (child - 1) / 2;while (child > 0) {if (a[child] > a[parent]) {swap(a, child, parent);}child = parent;parent = (child - 1) / 2;}}void adjustdown(int* a, int parent,int size) {int child = parent * 2 + 1;while (child < size) {if (child + 1 < size && a[child + 1] > a[child]) {child++;}if (a[child] > a[parent]) {swap(a, child, parent);}parent = child;child = parent * 2 + 1;}}
void HeapSort(int* a, int n) {assert(a);for (int i = n - 1; i > 0; i--) {adjustup(a, i);//逐个遍历}int end = n - 1;while (end > 0) {swap(a, end, 0);adjustdown(a,0,end);end--;}
}

这里我们是可以进一步优化的,因为向上调整算法可以有向下调整算法来代替。
算法优化就交给你完成了。

3 时间复杂度分析

让我们和之前的排序算法来比较一下。依然是10万组数据,让我们看一下运行时间。(以冒泡排序为对照)
在这里插入图片描述

显然选择排序和插入排序是一个级别,堆排序和希尔排序都非常快速。
我们再来比较一下希尔排序与堆排序。100万组数据
在这里插入图片描述
这里希尔貌似更快,但其实希尔排序与堆排序是一个量级,甚至在更多数据下,堆排序会更优。

Thanks♪(・ω・)ノ

下一篇文章见!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/299033.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue在页面上添加水印

第一步&#xff1a;在自己的项目里创建一个js文件&#xff1b;如图所示我在在watermark文件中创建了一个名为waterMark.js文件。 waterMark.js /** 水印添加方法 */ let setWatermark (str1, str2) > {let id 1.23452384164.123412415if (document.getElementById(id) …

WPF中数据绑定转换器Converter

使用场景&#xff1a;ViewModel中的数据如果跟View中的数据类型不匹配。 下面是以int类型调控是否可见为例子 步骤一&#xff1a;创建转换器类 在xaml中查看Converter的定义可以知道Converter是一个接口类型&#xff0c;因此转换器的类定义需要使用这个接口 internal class Vi…

计算机视觉技术-使用图像增广进行训练

让我们使用图像增广来训练模型。 这里&#xff0c;我们使用CIFAR-10数据集&#xff0c;而不是我们之前使用的Fashion-MNIST数据集。 这是因为Fashion-MNIST数据集中对象的位置和大小已被规范化&#xff0c;而CIFAR-10数据集中对象的颜色和大小差异更明显。 CIFAR-10数据集中的前…

如何使用Docker部署Dashy并无公网ip远程访问管理界面

文章目录 简介1. 安装Dashy2. 安装cpolar3.配置公网访问地址4. 固定域名访问 简介 Dashy 是一个开源的自托管的导航页配置服务&#xff0c;具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。你可以将自己常用的一些网站聚合起来放在一起&#xff0c;形成自己的导航…

不同参数规模大语言模型在不同微调方法下所需要的显存总结

原文来自DataLearnerAI官方网站&#xff1a; 不同参数规模大语言模型在不同微调方法下所需要的显存总结 | 数据学习者官方网站(Datalearner)https://www.datalearner.com/blog/1051703254378255 大模型的微调是当前很多人都在做的事情。微调可以让大语言模型适应特定领域的任…

WordPress主题大前端DUX v8.3源码下载

DUX主题8.3版本更新内容&#xff1a; 新增&#xff1a;Cloudflare Turnstile 免费验证功能 新增&#xff1a;子菜单页面模版&#xff0c;支持多级页面 新增&#xff1a;手机端文章内表格自动出现横向滚动条&#xff0c;可集体或单独设置滚动宽度 新增&#xff1a;标签云页面模版…

springboot 共享自习室座位管理系统 -计算机毕业设计源码55732

摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出去&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤&#xff0c;采用Java技术建设共享自习室座位管理系…

零基础入门网络安全必看的5本书籍(附PDF)

书中自有黄金屋&#xff0c;书中自有颜如玉。很多人学习一门技术都会看大量的书籍&#xff0c;经常也有朋友询问&#xff1a;零基础刚入门&#xff0c;应该看哪些书&#xff1f;应该怎么学&#xff1f;等等问题。今天就整理了5本零基础入门网络安全必看书籍&#xff0c;希望能帮…

overleaf 支持中文

基本操作 左上角menu中&#xff0c;切换compiler 到xelatex。 然后在\documentclass声明下面加一个 \usepackage{ctex}。 使用\usepackage{xecjk}可能也可以&#xff0c;但会有警告。 警告分析 Font “FandolSong-Regular” does not contain requested Script “CJK”。 网上…

关于标准那些事——第五篇 两仪

国家标准的编写&#xff0c;对于标准的名称和结构&#xff0c;很多人往往是不那么在意的&#xff0c;但这恰恰也是非常重要的点&#xff0c;今天就给大家分享一下这太极所生的“两仪”。我会用最精简的文字概括出核心内容&#xff0c;让大家有一个初步且完整的概念&#xff0c;…

什么是OAuth2.0

前言 OAuth&#xff08;Open Authorization&#xff09;是一个关于授权&#xff08;authorization&#xff09;的开放网络标准&#xff0c;允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息&#xff0c;而不需要将用户名和密码提供给第三方移动应用或分享他们数…

亚信安慧AntDB数据库:引领数据库标准与性能规范,推动行业创新

近日&#xff0c;全国信息技术标准化技术委员会数据库标准工作组在一场重要的研讨会上召开&#xff0c;旨在交流并总结2023年上半年数据库标准编制情况。我国自主研发的AntDB数据库&#xff0c;作为国内最早的国产数据库产品之一&#xff0c;受邀参与了此次标准的研讨&#xff…