排序-选择排序与堆排序

文章目录

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


一、选择排序

思想:
将数组第一个元素作为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;//迭代
		}
		else
			break;
	}
}
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.mfbz.cn/a/237233.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用NCNN在华为M5部署MobileNet-SSD

一、下载ncnn-android-vulkan ncnn-android-vulkan.zip 文件是一个压缩文件&#xff0c;其中包含了 ncnn 框架在 Android 平台上使用 Vulkan 图形库加速的相关文件和代码。 在 Android 平台上&#xff0c;ncnn 框架可以利用 Vulkan 的并行计算能力来进行神经网络模型的推理计…

算法——位运算

常见位运算总结 基础位运算 << >> ~与&&#xff1a;有0就是0或|&#xff1a;有1就是1异或^&#xff1a;相同为0&#xff0c;相异为1 / 无进位相加 给一个数n&#xff0c;确定他的二进制表示中的第x位是0还是1 让第x位与上1即可先让n右移x位&上一个1&#…

【docker三】Docker镜像的创建方法

目录 一、Docker镜像&#xff1a; 1、 镜像的概念 2、docker的创建镜像方式&#xff1a; 1.1、基于已有镜像进行创建&#xff1a; 1.2、基于模版创建&#xff1a; 1.3、基于dockerfile创建&#xff1a; 二、Dockerfile概述 1、Dockerfile概念&#xff1a; 2、dockerfile…

【UI自动化测试】appium+python+unittest+HTMLRunner

简介 获取AppPackage和AppActivity 定位UI控件的工具 脚本结构 PageObject分层管理 HTMLTestRunner生成测试报告 启动appium server服务 以python文件模式执行脚本生成测试报告 下载与安装 下载需要自动化测试的App并安装到手机 获取AppPackage和AppActivity 参考&#xff…

AWS攻略——使用中转网关(Transit Gateway)连接不同区域(Region)VPC

文章目录 Peering方案Transit Gateway方案环境准备创建Transit Gateway Peering Connection接受邀请修改中转网关路由修改被邀请方中转网关路由修改邀请方中转网关路由 测试修改Public子网路由 知识点参考资料 区别于 《AWS攻略——使用中转网关(Transit Gateway)连接同区域(R…

云降水物理基础

云降水物理基础 云的分类 相对湿度变化方程 由相对湿度的定义&#xff0c;两边取对数之后可以推出 联立克劳修斯-克拉佩龙方程&#xff08;L和R都为常数&#xff09; 由右式看出&#xff0c;增加相对湿度的方式&#xff1a;增加水汽&#xff08;de增大&#xff09;和降低…

SpringData JPA 搭建 xml的 配置方式

1.导入版本管理依赖 到父项目里 <dependencyManagement><dependencies><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-bom</artifactId><version>2021.1.10</version><scope>…

全新UI彩虹外链网盘系统源码V5.5/支持批量封禁+优化加载速度+用户系统与分块上传

源码简介&#xff1a; 全新UI彩虹外链网盘系统源码V5.5&#xff0c;它可以支持批量封禁优化加载速度。新增用户系统与分块上传。 彩虹外链网盘&#xff0c;作为一款PHP网盘与外链分享程序&#xff0c;具备广泛的文件格式支持能力。它不仅能够实现各种格式文件的上传&#xff…

数据接口测试工具 Postman 介绍!

此文介绍好用的数据接口测试工具 Postman&#xff0c;能帮助您方便、快速、统一地管理项目中使用以及测试的数据接口。 1. Postman 简介 Postman 一款非常流行的 API 调试工具。其实&#xff0c;开发人员用的更多。因为测试人员做接口测试会有更多选择&#xff0c;例如 Jmeter…

LeetCode-周赛-思维训练-中等难度

第一题 1798. 你能构造出连续值的最大数目 解题思路 我们先抛开原题不看&#xff0c;可以先完成一道简单的题目&#xff0c;假设现在就给你一个目标值X&#xff0c;问你能够构造出从【1~X】的连续整数&#xff0c;最小需要几个数&#xff1f; 贪心假设期望&#xff1a;我们要…

node14升级node16之后,webpack3项目无法启动处理

node从14升级到16之后&#xff0c;项目就无法启动了&#xff0c;研究了webpack3升级5&#xff0c;研究好几个小时都无法启动&#xff0c;最后发现&#xff0c;微微升级几个版本就可以了。webpack还是3 版本改了好多个的&#xff0c;但是不确定具体是哪几个起作用的&#xff0c;…

【LVGL】STM32F429IGT6(在野火官网的LCD例程上)移植LVGL官方的例程(还没写完,有问题 排查中)

这里写目录标题 前言一、本次实验准备1、硬件2、软件 二、移植LVGL代码1、获取LVGL官方源码2、整理一下&#xff0c;下载后的源码文件3、开始移植 三、移植显示驱动1、enable LVGL2、修改报错部分3、修改lv_config4、修改lv_port_disp.c文件到此步遇到的问题 Undefined symbol …

Docker中部署ElasticSearch 和Kibana,用脚本实现对数据库资源的未授权访问

图未保存&#xff0c;不过文章当中的某一步骤可能会帮助到您&#xff0c;那么&#xff1a;感恩&#xff01; 1、docker中拉取镜像 #拉取镜像 docker pull elasticsearch:7.7.0#启动镜像 docker run --name elasticsearch -d -e ES_JAVA_OPTS"-Xms512m -Xmx512m" -e…

数字图像处理(实践篇)二十一 人脸识别

目录 1 安装face_recognition 2 涉及的函数 3 人脸识别方案 4 实践 使用face_recognition进行人脸识别。 1 安装face_recognition pip install face_recognition 或者 pip --default-timeout100 install face_recognition -i http://pypi.douban.com/simple --trusted-…

c#读取XML文件实现晶圆wafermapping显示demo计算电机坐标控制电机移动

c#读取XML文件实现晶圆wafermapping显示 功能&#xff1a; 1.读取XML文件&#xff0c;显示mapping图 2.在mapping视图图标移动&#xff0c;实时查看bincode,x,y索引与计算的电机坐标 3.通过设置wafer放在平台的位置x,y轴电机编码值&#xff0c;相机在wafer的中心位置&#…

类与接口常见面试题

抽象类和接口的对比 抽象类是用来捕捉子类的通用特性的。接口是抽象方法的集合。 从设计层面来说&#xff0c;抽象类是对类的抽象&#xff0c;是一种模板设计&#xff0c;接口是行为的抽象&#xff0c;是一种行为的规范。 相同点 接口和抽象类都不能实例化都位于继承的顶端…

每日一题,头歌平台c语言题目

任务描述 题目描述:输入一个字符串&#xff0c;输出反序后的字符串。 相关知识&#xff08;略&#xff09; 编程要求 请仔细阅读右侧代码&#xff0c;结合相关知识&#xff0c;在Begin-End区域内进行代码补充。 输入 一行字符 输出 逆序后的字符串 测试说明 样例输入&…

老师们居然这样把考试成绩发给家长

教育是一个复杂而多元的过程&#xff0c;其中考试成绩的发布和沟通是教育过程中的一个重要环节。然而&#xff0c;有些老师在发布考试成绩时&#xff0c;采取了一些不恰当的方式&#xff0c;给家长和学生带来了不必要的困扰和压力。本文将探讨老师们不应该采取的发布考试成绩的…

六级高频词组1

目录 词组 参考链接 词组 1. abide by&#xff08;be faithful to &#xff1b;obey&#xff09;忠于&#xff1b;遵守。 2. be absent from… 缺席&#xff0c;不在 3. absence or mind&#xff08;being absent-minded&#xff09; 心不在焉 4. absorb&#xff08;take …

进程的同步和异步、进程互斥

一、进程同步和异步 同步&#xff08;Synchronous&#xff09;&#xff1a; 同步指的是程序按照顺序执行&#xff0c;一个操作完成后才能进行下一个操作。在多进程或多线程的环境中&#xff0c;同步意味着一个进程&#xff08;或线程&#xff09;在执行某个任务时&#xff0c;…
最新文章