【数据结构--排序】堆排序

news2024/11/23 0:49:06

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

  • 堆排序
    • 一、🌱排降序
      • 1.思路:
      • 2.代码实现:
      • 3.测试结果
      • 4.总代码
    • 二、🌸排升序
      • 1.思路:
      • 2.代码实现:
      • 3.测试结果:
      • 4.总代码
    • 三、堆排序的时间复杂度

堆排序

一、🌱排降序

口诀:排降序,建小堆

1.思路:

(1)首先使用从下到上的方法建立小堆;如下图

在这里插入图片描述

(2)堆顶与最后一个节点交换,由于是小堆,堆顶是最小值。交换后,就选出了最小值并将其放到数组的组后位置,
在这里插入图片描述

(3).将堆的长度减1【end–】(数组长度减1)。
(4).在对剩下的堆进行基于小堆的向下调整,从而将第二小的数调整到了堆顶。
在这里插入图片描述

重复步骤2.3.4,end一直减到0;
4.最后,这个原本存储小堆的数组,就变成了一个从小到大的降序数组。
在这里插入图片描述

2.代码实现:

1.交换

//交换
void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

2.修改AdjustDown(a, end, 0);为调小堆


基于小堆的向下调整
```c
//基于大堆的向下调整
void AdjustDownxiao(int* a, int n, int parent)
{
	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
		{
			return;
		}
	}
}

3.排降序

void HeapSortDES(int* a, int n)
{
	//建立小堆
	for (int i = (n-1-1)/2; i >= 0; i--)
	{
		AdjustDownxiao(a, n, i);
	}

	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		//每次调整从根0到end,end每次会减1。
		AdjustDownxiao(a, end, 0);
		--end;
	}
}

3.测试结果

在这里插入图片描述

4.总代码

//交换
void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
//基于小堆的向下调整
void AdjustDownxiao(int* a, int n, int parent)
{
	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
		{
			return;
		}
	}
}

//降序
void HeapSortDES(int* a, int n)
{
	//建立小堆
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDownxiao(a, n, i);
	}

	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		//每次调整从根0到end,end每次会减1。
		AdjustDownxiao(a, end, 0);
		end--;
	}
}


二、🌸排升序

口诀:排升序,建大堆

意思是:想要将数组的顺序变成一个升序的,那么可以建立一个大堆存在数组中,在对堆进行调整。即可将数组变成一个升序数组。

1.思路:

首先使用从下到上的方法建立大堆;
1.堆顶与最后一个节点交换,由于是大堆,堆顶是最大值。交换后,就选出了最大值并将其放到数组的组后位置
2.并将堆的长度减1(数组长度减1)。
3.在对剩下的堆进行基于大堆的向下调整从而将第二大的数调整到了堆顶
4.最后,这个原本存储大堆的数组,就变成了一个从小到大的升序数组

2.代码实现:

1.交换

//交换
void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

2.基于大堆的向下调整

//基于大堆的向下调整
void AdjustDown(int* a, int n, int parent)
{
	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
		{
			return;
		}
	}
}

3.排升序

//排升序
void HeapSortASC(int* a, int n)
{
	//建立大堆
	for (int i = (n-1-1)/2; i >= 0; i--)
	{
		AdjustDown(a, n, i);
	}

	int end = n - 1;
	while (end > 0)
	{
		swap(&a[0], &a[end]);
		//每次调整从根0到end,end每次会减1。
		AdjustDown(a, end, 0);
		end--;
	}
}

3.测试结果:

在这里插入图片描述

4.总代码

//交换
void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
void AdjustDown(int* a, int n, int parent)
{
	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
		{
			return;
		}
	}
}




//升序
void HeapSortASC(int* a, int n)
{
	//建立小堆
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, n, i);
	}

	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		//每次调整从根0到end,end每次会减1。
		AdjustDown(a, end, 0);
		end--;
	}
}

三、堆排序的时间复杂度

堆排序分两步:1.建堆(使用时间复杂度更低的向下调整建堆)2.排序

向下调整建堆的时间复杂度为O(n);
n-1次删除操作的时间复杂度为O(nlogn);
所以总操作时间复杂度为O(nlogn)

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

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

相关文章

Java 项目-基于 SpringBoot+Vue的疫情网课管理系统

文章目录 第一章 简介第二章 技术栈第三章 系统分析3.4.2学生用例 第四章 系统设计第五章 系统实现5.1学生功能模块5.2管理员功能模块5.3教师功能模块 六 源码咨询 第一章 简介 疫情网课也都将通过计算机进行整体智能化操作&#xff0c;实现的功能如下。 例如 管理员&#x…

如何监控公司电脑上网记录(员工上网行为监控软件有哪些?)

在当今数字化的世界中&#xff0c;互联网已经成为企业运营的重要组成部分。然而&#xff0c;随着这一转变&#xff0c;企业也面临着新的挑战&#xff0c;尤其是关于员工上网行为监控的问题。本文旨在解释公司上网行为监控的含义&#xff0c;重要性&#xff0c;实施方法以及最佳…

msvcp100.dll丢失原因,电脑出现msvcp100.dll丢失错误的解决方法

msvcp100.dll 是一个动态链接库文件&#xff0c;它包含了 C 运行时库的一些函数和类&#xff0c;例如全局对象、异常处理、内存管理、文件操作等。它是 Visual Studio 2010 及以上版本中的一部分&#xff0c;用于支持 C 应用程序的运行。如果 msvcp100.dll 丢失或损坏&#xff…

记一次linux下pip安装包时出错及奇怪的解决过程

一、问题说明 如图&#xff0c;在使用pip安装测速工具speedtest-cli时&#xff0c;终端提示“Externally managed environment &#xff08;从外部管理的环境&#xff09;”&#xff0c;导致无法安装该库。 二、问题解决 1 尝试提示的解决方案&#xff0c;改用命令apt inst…

C++【个人笔记1】

1.C的初识 1.1 简单入门 #include<iostream> using namespace std; int main() {cout << "hello world" << endl;return 0; } #include<iostream>; 预编译指令&#xff0c;引入头文件iostream.using namespace std; 使用标准命名空间cout …

qt 打印当前路径

//当前根目录qDebug()<< QDir::currentPath();//当前exe目录qDebug()<< QCoreApplication::applicationDirPath();//当前exe路径qDebug()<< QCoreApplication::applicationFilePath();分别输出&#xff1a;

文件储存平方根

任务描述 本关任务&#xff1a;给定程序中&#xff0c;函数fun的功能是将自然数1&#xff5e;10以及它们的平方根写到名为myfile3.txt的文本文件中&#xff0c;然后再顺序读出显示在屏幕上。请不要增行或删行&#xff0c;或更改程序的结构。 相关知识 相关知识略 编程要求 …

【Android Framework系列】第17章 Android Q沙箱模式(Scoped Storage)

1 背景 上一章节【Android Framework系列】第16章 存储访问框架 (SAF) 主要分析了Android4.4引入的存储访问框架&#xff08;SAF&#xff09;&#xff0c;本章节我们对Android10&#xff08;Q&#xff09;的存储相关进行分析&#xff0c;了解下其限制存储方式。 Google为了让…

oracle19c 集群部署的问题汇总

1、互信报错 处理过程 01、发现/etc/sysctl.conf中有net.ipv4.icmp_echo_ignore_all1配置&#xff0c;注释后发现还是无法通过 02、# cat /proc/sys/net/ipv4/icmp_echo_ignore_all发现返回1&#xff0c;说明还是禁ping&#xff0c;两个节点执行# echo 0 > /proc/sys/net…

dosbox调试模式下0000:0000地址中内容被修改的原因

跟着王爽老师学习汇编&#xff0c;执行以下指令时&#xff0c;发现自己手动算出来的和dosbox验证的不一致 dosbox用的是debug模式&#xff0c;确保了内存数据和指令都完全一致的情况下&#xff0c;逐步执行&#xff0c;发现写在0000:0000位置的内存数据在执行add命令的时候被修…

改写软件-怎么选择改写软件

什么是改写软件&#xff1f;改写软件是基于自然语言处理技术的工具&#xff0c;它们可以分析一段文字&#xff0c;并将其重新表达&#xff0c;以保持原始意义&#xff0c;但使用不同的词汇和结构。这种技术可用于减少内容的重复&#xff0c;增加多样性&#xff0c;或者简化复杂…

小说推文授权和短剧推广渠道的介绍怎么申请

新赛道小说推文和短剧推广怎么申请授权的&#xff1f; 可以通过”巨量推文“进行授权 只需要通过平台申请对应的推广信息&#xff08;短剧或小说&#xff09;通过后即可展开推广 具体的推广方式也都有资料

阿里云产品试用系列-容器镜像服务 ACR

阿里云容器镜像服务&#xff08;简称 ACR&#xff09;是面向容器镜像、Helm Chart 等符合 OCI 标准的云原生制品安全托管及高效分发平台。 ACR 支持全球同步加速、大规模/大镜像分发加速、多代码源构建加速等全链路提效&#xff0c;与容器服务 ACK 无缝集成&#xff0c;帮助企业…

java服务内存说明及配置详解

java进程内存 JVM内存分布图: 【java进程内存】【堆外内存】 【jvm堆内存】 【堆外内存】 【Metaspace】 【Direct Memory】【JNI Memory】【code_cache】 … 堆外内存泄漏的排查在于【本地内存&#xff08;Native Memory&#xff09;】【Direct Memory】【JNI Memory】 一般…

Android---打开相机拍照

简单实现打开系统系统相机拍一张图片并显示在UI上&#xff0c;适用与个人主页头像的切换。 1. 添加权限。AndroidManifest.xml里添加使用相机的权限。 <uses-permission android:name"android.permission.CAMERA"/> 2. 布局。布局内容比较交单&#xff0c;一…

Ubuntu上安装、使用Redis的详细教程

这篇文章简单地介绍一下怎么在linux虚拟机上完成redis的安装及使用。 目录 1、安装redis 2、使用redis 3、启动/关闭redis 启动redis 启动方式一 启动方式二 启动方式三 重启redis 关闭redis 查看redis状态 4、在宿主机连接redis 5、通过java连接redis 创建maven项…

Webpack监视文件修改,自动重新打包文件

方法一&#xff1a;使用watch监视文件变化 在终端中输入以下指令&#xff1a; npx webpack --watch 我们使用这种方法监听文件变化时只会监听我们计算机本地的文件变化&#xff0c;在开发场景中我们的项目是要部署到服务器中的&#xff0c;因此这种方式并不推荐。 方法二&…

proteus中的各种电阻-可变电阻-排阻

在原理图中使用各类型的电阻是很常见的事情&#xff0c;尤其类似与排阻、可变电阻&#xff0c;但这些电阻对于不熟悉proteus的童鞋来说&#xff0c;一下子可能很难找到&#xff0c;或者很难找心中所想的那个类型&#xff0c;这里分类列出&#xff0c;便于大家使用。 文章目录 一…

Kubernetes集群+Keepalived+Nginx+防火墙实例

文章目录 实验前期规划1.拓扑图结构2.实验要求3.实验环境规划 一.kubeadm 部署 K8S 集群架构1.环境准备2.三个节点安装docker3.三个节点安装kubeadm&#xff0c;kubelet和kubectl4.部署K8S集群&#xff08;1&#xff09;初始化&#xff08;2&#xff09;部署网络插件flannel&am…

腾讯云COS+Picgo+Typora图床搭建

文章目录 什么是图床&#xff1f;配置腾讯云COS整体流程注册腾讯云账号并开通配置COS下载并配置PicGoTypora配置PicGo 可视化管理工具 什么是图床&#xff1f; 百度百科是这样解释的&#xff1a; 图床一般是指储存图片的服务器&#xff0c;有国内和国外之分。国外的图床由于有…