排序-选择排序与堆排序

文章目录

    • 一、选择排序
    • 二、堆排序
    • 三、时间复杂度
    • 四、稳定性


一、选择排序

思想:
将数组第一个元素作为min,然后进行遍历与其他元素对比,找到比min小的数就进行交换,直到最后一个元素就停止,然后再将第二个元素min,再遍历,以此下去直到最后一个数据
流程图:
在这里插入图片描述
代码实现:

//交换
void Swap(int* a,int* b) {int t = *a;*a = *b;*b = t;
}
//打印
void Print(int* arr, int n) {for (int i = 0;i < n; i++)printf("%d ", arr[i]);
}
//直接选择排序
void SelectSort(int* arr, int size) {for (int i = 0; i < size; i++){int min = i;//从第一个开始//每次从i+1的位置开始就不会影响到前面的了for (int j = i+1; j < size; j++) {//比较if (arr[min] > arr[j])min =j;//记录下标}Swap(&arr[i], &arr[min]);//交换}}
int main() {int arr[] = { 43152};
SelectSort(arr, sizeof(arr) / sizeof(arr[0]));
Print(arr, sizeof(arr) / sizeof(arr[0]));return 0;
}

运行结果:
在这里插入图片描述
选择排序优化:
我们可以设置一个min和一个max,将小的放到左边,大的放到右边,我们再设置两个控制左右两边下标的变量p,q,当它们相遇时就结束。
流程图:
在这里插入图片描述
特殊情况:max的位置等于p时,我们先交换arr[p]和arr[min],但是max指向p这个位置,但是p这位置的值已经改变了,这时我们就要进行纠正,将max=min,这样才能成功找到原来在p位置的值
如:
在这里插入图片描述
代码实现:

//交换
void Swap(int* a,int* b) {int t = *a;*a = *b;*b = t;
}
//打印
void Print(int* arr, int n) {for (int i = 0;i < n; i++)printf("%d ", arr[i]);
}
//优化选择排序void SelectSort1(int* arr, int size) {int p = 0, q = size-1;//p指向数组开头,q指向数组最后一个位置while (p < q) {//当错过或者相遇就结束int min = p, max = p;//迭代位置for (int i = p; i <= q; i++){if (arr[min] > arr[i])//找到最小值min = i;if (arr[max] < arr[i])//找到最大值max = i;}Swap(&arr[min], &arr[p]);//交换if (max == p)//5 2 3 4 1//判断是否要纠正max = min;Swap(&arr[max], &arr[q]);//交换p++, q--;}
}
int main() {int arr[] = { 4,3,1,5,2 };SelectSort1(arr, sizeof(arr) / sizeof(arr[0]));Print(arr, sizeof(arr) / sizeof(arr[0]));return 0;
}

运行结果:
在这里插入图片描述

二、堆排序

堆:

结构性:用数组表示的完全二叉树;
有序性:任一结点的关键字是其子树所有结点的最大值(或最小值)
“最大堆(MaxHeap)”,也称“大顶堆”,即最大值所有父亲大于等于孩子
“最小堆(MinHeap)”,也称“小顶堆”,即最小值所有父亲小于等于孩子

小堆:堆顶数据是最小的,并且所有节点都小于左右子树
在这里插入图片描述

大堆:堆顶数据是最大的 ,并且所有节点都大于左右子树
在这里插入图片描述
用堆来实现排序:
(1)使用向下调整算法:
前提:左右子树必须是小堆或者大堆
作用:建堆
如:
左右子树对比选择,再与根比较
在这里插入图片描述
(2)建堆
当我们要实现升序时,通过向下调整法要建大堆
建的过程:因为使完全二叉树,我们可以从最后非叶点节点开始建,直到没有节点就结束。
如:
建大堆
在这里插入图片描述
找左右子树位置:

树的左子树的下标等于根的下标*2+1,的下标等于根的下标 *2+2

建完后,我们可以将最后一个元素和第一个元素交换,然后再做向下调整即可不用重新建堆了,再让第一个元素和倒数第二个元素交换,以此类推…
为什么不建小堆呢?如果建小堆的话,用第一个根(最小值)就是数组的第一个元素了,我们不能动它,那么再让数组的第二元素重新做根,但是这样的话顺序就会被打破,又要重新建堆了,那样时间复杂度会提高(如何实现降序的话可以建小堆)

代码实现:

//交换
void Swap(int* a,int* b) {int t = *a;*a = *b;*b = t;
}
//打印
void Print(int* arr, int n) {for (int i = 0;i < n; i++)printf("%d ", arr[i]);
}
//向下调整  大堆
void AdjustDwon(int *arr,int p,int size) {int q = p;//节点位置int z = q * 2 + 1;//节点左子树,z+1就是右子树的位置了while (z<size) {//当z大于数组长度时就说明该节点不存在左右子树//判断左右子树大小,后面是判断是否有右子树if (arr[z] <arr[z + 1]&&z+1<size)z += 1;if (arr[z] > arr[q]) {//判断是否比根大Swap(&arr[z], &arr[q]);q = z;z = q * 2 + 1;//迭代}elsebreak;}
}
void  HeapSort(int* arr,  int size) {//建堆,size-1-1就是除2(求子树公式反过来用,最后减一是因为我们求的是下标)for (int i = (size - 1 - 1) / 2; i >= 0; i--) {AdjustDwon(arr, i, size);}int ned = size - 1;
//最后一个下标位置开始,和下标为0的元素交换,一直交换下去,并且交换一次就调整一次//当ned==1就证明排好了while (ned>0) {Swap(&arr[0], &arr[ned]);AdjustDwon(arr, 0, ned);//重新调整ned--;}
}int main() {int arr[] = { 4,3,1,5,2 };HeapSort(arr, sizeof(arr)/sizeof(arr[0]));Print(arr, sizeof(arr) / sizeof(arr[0]));
return 0}

运行结果:
在这里插入图片描述

三、时间复杂度

选择排序:
n-1 ,n-2…2,1
是一个等差数列求前n-1项和,粗略来算就是n^2
所以时间复杂度为O(n^2)

堆排序:
建堆:O(n)
在这里插入图片描述
向下调整的时间复杂度为:
假设树高为 h,树的结点为n,因为n=2^h-1,那么h=log(n-1)(以2为底)
所以为O(logn-1)
我们还要进行n次这个向下调整(当然在进行的过程中n是会变化的)
那么总的次数n+nlogn
所以时间复杂度为O(n
logn)

四、稳定性

稳定性:

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[4],且r[1]在r[4]之前,而在排序后的序列中,r[1]仍在r[4]之前,则称这种排序算法是稳定的;否则称为不稳定的。

选择排序:不稳定
如:
在这里插入图片描述
堆排序:不稳定
在这里插入图片描述
第一个9直接到最后了

以上就是我的分享了,如果有什么错误,欢迎在评论区留言。
最后,谢谢大家的观看!

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

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

相关文章

【单调栈】【二分查找】LeetCode: 2454.下一个更大元素 IV

作者推荐 【动态规划】【广度优先】LeetCode2258:逃离火灾 本文涉及的基础知识点 二分查找算法合集 单调栈 题目 给你一个下标从 0 开始的非负整数数组 nums 。对于 nums 中每一个整数&#xff0c;你必须找到对应元素的 第二大 整数。 如果 nums[j] 满足以下条件&#xff…

音视频技术开发周刊 | 323

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 Meta牵头组建开源「AI复仇者联盟」&#xff0c;AMD等盟友800亿美元力战OpenAI英伟达 超过50家科技大厂名校和机构&#xff0c;共同成立了全新的人工智能联盟。以开源为旗号…

es6从url中获取想要的参数

第一种方法 很古老&#xff0c;通过 split 方法慢慢截取&#xff0c;可行是可行但是这个方法有一个弊端&#xff0c;因为 split 是分割成数组了&#xff0c;只能按照下标的位置获取值&#xff0c;所以就是参数位置一旦发生变化&#xff0c;那么获取到的值也就错位了 let user…

利用python将data:image/jpg; base64,格式数据转化下载为图片

在做爬虫爬取图片时&#xff0c;发现有的图片url是用“data:image/jpg;base64” 开头的&#xff0c;例如下图 部分开头样式如下&#xff1a; 1、data:image/jpg; base64, 2、data:image/png; base64, 3、data:image/webp;base64, 利用python进行代码进行图片下载&#xff0c;…

先进的Web3.0实战热门领域NFT项目几个总结分享

非同质化代币&#xff08;NFT&#xff09;的崛起为游戏开发者提供了全新的机会&#xff0c;将游戏内物品和资产转化为真正的可拥有和交易的数字资产。本文将介绍几个基于最先进的Web3.0技术实践的NFT游戏项目&#xff0c;并分享一些相关代码。 Axie Infinity&#xff08;亚龙无…

智能优化算法应用:基于猫群算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于猫群算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于猫群算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.猫群算法4.实验参数设定5.算法结果6.参考文献7.MA…

件夹和文件比较软件VisualDiffer mac功能介绍

VisualDiffer mac是一款运行在MacOS上的文件夹和文件快速比较工具。VisualDiffer可以对不同文件夹中文件或文档做出比较或者比较两个文件的路径。还可以通过UNIS diff命令快速、标准和可靠的比较出各类不同的文件夹和文件结果&#xff0c;使用不同的颜色直观地显示。 VisualDif…

酷滴科技出席浦发银行第七届国际金融科技创新大赛

12月7日&#xff0c;浦发银行全球金融科技创新大赛在上海展开决赛。本届大会以“科技金融&#xff0c;激发创新力量”为主题&#xff0c;聚焦金融行业数字化转型过程中的痛点与难点&#xff0c;旨在探讨新时代下金融科技的新角色、新机遇以及新挑战。酷滴科技CEO张沈分享了酷滴…

12.11

1.q&#xff0c;w&#xff0c;e亮led1&#xff0c;2&#xff0c;3&#xff1b; a&#xff0c;s&#xff0c;d灭led1&#xff0c;2&#xff0c;3&#xff1b; main.c #include "uar1.h"#include "led.h"void delay(int ms){int i,j;for(i0;i<ms;i){for…

SQL中的三值逻辑:TRUE、FALSE 和 UNKNOWN。

在SQL中&#xff0c;通常采用三值逻辑处理条件表达式的真值。这种逻辑是基于三种可能的真值状态&#xff1a;TRUE、FALSE 和 UNKNOWN。 TRUE&#xff08;真&#xff09;&#xff1a; 表示条件为真或成立。 FALSE&#xff08;假&#xff09;&#xff1a; 表示条件为假或不成立。…

7 Linux 内核移植

一、编译 ST 的 Linux 系统 1. 压缩源码 首先先下载 ST 官方源码&#xff0c;之前章节已经下载过了&#xff0c;直接输入以下命令&#xff1a; cd linux/atk-mpl/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi/linux-stm32mp-5.4.31-r0/ 然…

EasyExcel使用模板导出复杂Excel

1&#xff09;添加easyexlce的依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.0-beta1</version> </dependency>2&#xff09;添加excel模板文件 实现的效果&#xff1a;…

打包less

接HTML和css之后对less进行打包 1.在之前的文件夹里的src文件夹创建一个less文件 2.打开webpack——>中文文档——>Loader——>less—loader 3.复制下图代码到终端 4.复制下图内容到webpack.config.js脚本 5.在src里的js文件年引入less文件 6.在终端运行 npm run te…

助力工业生产质检,基于轻量级yolov5-seg开发构建工业场景下滚珠丝杠传动表面缺陷分割检测系统

AI赋能工业生产是一个强有力的方式&#xff0c;在我们之前的系列博文中也有很多相应的开发实践&#xff0c;感兴趣的胡都可以自行移步阅读&#xff0c;本文的核心思想就是想要基于轻量级的实例分割模型来开发构建工业场景下的滚珠丝杠传动表面缺陷分割检测系统&#xff0c;首先…

STM32-固件打包部署

STM32-固件打包部署 Fang XS.1452512966qq.com STM32固件输出 工程上使用Keil开发STM32软件&#xff1b;在调试过程中&#xff0c;可直接编译下载&#xff1b;例如bootloader和APP&#xff0c;在调试时&#xff0c;可以直接下载2次&#xff1b;但是工程上&#xff0c;需要大…

力扣经典面试题——合并区间

合并区间 https://leetcode.cn/problems/merge-intervals/description/?envTypestudy-plan-v2&envIdtop-interview-150 这题思维量一般但比较考察API的使用。 1、数组的自定义排序 2、数组的初始化定义 3、Arrays转int 通过重写Comparator的compare方法来自定义排序规则…

Spring Boot监听redis过期的key

Redis支持过期监听&#xff0c;可以实现监听过期数据&#xff0c;实现过程如下 1、pom依赖 <!-- Redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></depend…

Django讲课笔记02:Django环境搭建

文章目录 一、学习目标二、相关概念&#xff08;一&#xff09;Python&#xff08;二&#xff09;Django 三、环境搭建&#xff08;一&#xff09;安装Python1. 从官方网站下载最新版本的Python2. 运行安装程序并按照安装向导进行操作3. 勾选添加到路径复选框4. 完成安装过程5.…

【计算机网络】UDP报文详解

目录 一. UDP协议概述 二. UDP报文格式 首部 三. UDP的缓冲区 一. UDP协议概述 UDP——用户数据报协议&#xff0c;是传输层的一个重要协议 基于UDP的应用层协议有&#xff1a;DNS&#xff0c;TFTP&#xff0c;SNMP&#xff0c;NTP 协议全称默认端口号DNSDomain Name Se…

开源框架Apache NiFi调研

开源框架Apache NiFi调研 NiFi背景介绍一、什么是NiFi1.1 Apache NiFi特点&#xff1a;流管理、易用性、安全性、可扩展的体系结构和灵活的伸缩模型。1.2 Apache NiFi特性1.2 Apache NiFi核心概念1.3架构 二、NiFi的诞生&#xff0c;要致力于解决的问题有哪些&#xff1f;三、为…