堆排序的概念

news2024/11/23 7:19:41

文章目录

  • 一、堆(Heap)的基本概念
    • 1.1 引入二叉树的顺序存储
  • 二、建立大根堆
  • 三、基于大根堆进行排序

选择排序:在每一趟待排元素中选取关键字最小(或最大)的元素加入有序子序列

选择排序分为:

  • 简单选择排序
  • 堆排序

一、堆(Heap)的基本概念

若n个关键字序列L[1…n]满足下面某一条性质,则称为堆(Heap):

  • 若满足:L(i)≥L(2i)且L(i)≥L(2i+1)(1≤i≤n/2)–大根堆
  • 若满足:L(i)≤L(2i)且L(i)≤L(2i+1)(1≤i≤n/2) --小根堆

1.1 引入二叉树的顺序存储

在这里插入图片描述
有此可见,堆逻辑上可理解为一个顺序存储的完全二叉树

  • 大根堆–根>左,右的完全二叉树
  • 小根堆–根<左,右的完全二叉树

二、建立大根堆

基本思路:把所有分支结点检查一遍,判断是否满足大根堆的要求,如果不满足,则进行调整。

根据完全二叉树的性质

  • 2i<n
  • 2i+1<n
  • 叶子结点:i>n/2

故只需检查 i ≤ n / 2 i\leq n/2 in/2结点(分支结点)即可。二叉树从下往上调整(数组从后往前遍历)。如果不满足大根堆的条件,从左右孩子结点中挑较大的一个与根结点交换。


举例帮助理解:
在这里插入图片描述
i=8;只需检查 i ≤ 4 i\leq 4 i4的结点即可,即为上图圈出来的结点。二叉树从下往上调整,故从09开始,数组对应从后往前i=4向前遍历并令arr[0]=09暂存


代码实现

建立大根堆:

void buildMaxHead(int arr[], int length) {
	for (int i = length / 2; i >= 1; i--) {//从后往前遍历数组
		HeadAdjust(arr, i, length);
	}
}

将以k为根的子树调整为大根堆:

void HeadAdjust(int arr[], int k, int len) {
	arr[0] = arr[k];//key
	for (int i = 2 * k; i <= len; i*=2) {//延key不断向下检查子节点
		if (arr[i] < arr[i + 1] && i + 1 <= len) { //将i指向较大子孩子
			i++;
		}
		if (arr[0] >= arr[i])//当满足大根堆,退出
			break;
		else {
			arr[k] = arr[i];
			k = i;//修改k值,继续向下检查
		}
	}
	arr[k] = arr[0];//将key放入最后检查的位置
}

三、基于大根堆进行排序

堆排序:每一趟将堆顶元素加入有序子序列(与待排序序列中的最后一个元素交换)

并将待排序元素序列再次调整为大根堆(小元素不断“下坠”)

举例帮助理解
在这里插入图片描述
此时已经完成一次堆排序,堆顶元素为最大元素
在这里插入图片描述
堆顶元素队列末尾元素互换。接着不断进行HeadAdjust(arr,1,len-1)


完整代码实现

#include<iostream>
using namespace std;
int N;
int arr[100050];
void HeadAdjust(int arr[], int k, int len) {
	arr[0] = arr[k];
	for (int i = 2 * k; i <= len; i *= 2) {
		if (arr[i] < arr[i + 1] && i + 1 <= len) { //将i指向较大子孩子
			i++;
		}
		if (arr[0] > arr[i])
			break;
		else {
			arr[k] = arr[i];
			k = i;
		}
	}
	arr[k] = arr[0];
}
void buildMaxHead(int arr[], int length) {
	for (int i = length / 2; i >= 1; i--) {
		HeadAdjust(arr, i, length);
	}
}

int main() {
	cin >> N;
	for (int i = 1; i <= N; i++) {
		cin >> arr[i];
	}
	buildMaxHead(arr, N);//建立大根堆
	//基于大根堆的堆排序
	for (int i = N; i >= 1;) {
		int t = arr[i];
		arr[i] = arr[1];
		arr[1] = t;
		HeadAdjust(arr,1,--i);
	}
	for (int i = 1; i <= N; i++) {
		if (i != 1)
			cout << " ";
		cout << arr[i];
	}
}

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

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

相关文章

springboot+mybatis连接数据库实现增删改查功能

springbootmybatis连接数据库实现增删改查功能创建表创建项目实体类DAO接口写sql的XML文件Service层Controller启动类结果目录结构参考博客创建表 create table user(id int ,name varchar(30),pwd varchar(40) )insert into user values(2,hxf,789101),(3,hlm,789102),(4,hzh…

【ArcGIS自定义脚本工具】批量对栅格执行栅格计算器

文章目录一、功能介绍二、脚本代码三、工具参数四、用例4.1 批量单位换算4.2 批量计算植被覆盖度4.3 批量填充空值系列文章目录&#xff1a; ArcGIS自定义脚本工具一、功能介绍 功能 将多个栅格文件按照某以代数表达式执行栅格计算器(Raster Calculator) 工具&#xff0c;并将输…

linux内核内存笔记

一、linux用户态内核态内存结构 对于32位的linux操作系统&#xff0c;系统为每个进程分配0~4G的内存空间&#xff0c;而64位系统则更大&#xff1a; linux内存空间地址范围 可见Linux的内存分配规则&#xff1a; 二、总体分配规则 1、用户态在低地址&#xff0c;内核态在高地址…

进击中的 Zebec 生态,Web2 与 Web3 世界的连接器

虽然从意识形态上看&#xff0c;Web2世界与Web3世界存在着不同的逻辑&#xff0c;但我们同样看到&#xff0c;随着加密资产领域的发展&#xff0c;其正在作为优质投资品&#xff0c;被以Paypal、高盛等主流机构重视与接受。当然&#xff0c;除了作为投资者品外&#xff0c;近年…

C++学习笔记-环境设置

C 是一种通用编程语言&#xff0c;如今已广泛用于竞争性编程。它具有命令式&#xff0c;面向对象和通用编程功能。 C 在Windows&#xff0c;Linux&#xff0c;Unix&#xff0c;Mac等许多平台上运行。在开始使用C 进行编程之前。我们将需要在本地计算机上设置一个环境&#xff0…

用PHP实现CSPRepor报告预警信息存储和动态显示。

一、了解CSP内容安全策略 CSP 的实质就是白名单制度&#xff0c;开发者明确告诉客户端&#xff0c;哪些外部资源可以加载和执行&#xff0c;等同于提供白名单。它的实现和执行全部由浏览器完成&#xff0c;开发者只需提供配置。 作用就是&#xff1a;大大增强了网页的安全性。…

透明和半透明效果

Alpha通道 透明度可以通过base map的alpha通道来控制。Alpha值低的话&#xff0c;mesh就变得更加透明&#xff0c;alpha值高的话&#xff0c;mesh的透明度会变低&#xff0c;变得能更加轻松地被看到。当alpha为0时&#xff0c;mesh就完全不可见了&#xff0c;alpha值在中间时&a…

kubernetes(k8s) 知识总结(第2期)

1. “控制器”思想 kube-controller-manager 是一系列控制器的集合&#xff0c;这些控制器被放在 Kubernetes 项目的 pkg/controller 目录&#xff0c;这些控制器都以独有的方式负责某种编排功能。它们都遵循一个通用的编排模式——控制循环。 以 Deployment 为例介绍它对控…

最最普通程序员,如何利用工资攒够彩礼,成为人生赢家

今天我们不讲如何提升你的专业技能去涨工资&#xff0c;不讲面试技巧如何跳槽涨工资&#xff0c;不讲如何干兼职赚人生第一桶金&#xff0c;就讲一个最最普通的程序员&#xff0c;如何在工作几年后&#xff0c;可以攒够彩礼钱&#xff0c;婚礼酒席钱&#xff0c;在自己人生大事…

什么是网络流量分析(NTA),有什么好用的NTA软件

分析网络的稳定性首先要监控其性能、设备功能、网络速度以及许多网络管理员忽略的另一个方面&#xff1a;网络流量。网络流量分析 &#xff08;NTA&#xff09; 通常是考虑最少的方面&#xff0c;但它会影响许多问题&#xff0c;例如性能下降和用户速度缓慢。忽视它可能会让位于…

SQL语句实现找到一行中数据最大值(greatest)/最小值(least);mysql行转列

今日我在刷题时遇到这样一个题&#xff0c;它提到了以下需求&#xff1a; 有一场节目表演&#xff0c;五名裁判会对节目提供1-10分的打分&#xff0c;节目最终得分为去掉一个最高分和一个最低分后的平均分。 存在以下一张表performence_detail&#xff0c;包含字段有performa…

Docker安装RocketMQ 4.8

1拉取4.8镜像 docker pull foxiswho/rocketmq:4.8.0拉取控制台镜像 docker pull styletang/rocketmq-console-ng2创建rocketmq使用的共有网络&#xff0c;便于相互访问 docker network create rocketmq_network3启动rmqnamesrv docker run -d --name rmqnamesrv --network …

电脑录屏怎样不录到外界声音?调整这一个开关,即可实现

​有很多小伙伴希望自己电脑录屏的时候&#xff0c;不要录制自己的声音&#xff0c;而是通过后期配音的方式完成视频创作。电脑录屏怎样不录到外界声音&#xff1f;其实只需要调整这一个开关&#xff0c;就能实现不录外界声音&#xff0c;一起来看看吧。 不录外界声音1&#xf…

什么是 Java 泛型?

本文首发自「慕课网」&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注&#xff01; 作者| 慕课网精英讲师 ColorfulC 通过本篇文章你将了解到什么是泛型&#xff0c;为什么需要泛型&#xff0c;如何使用泛型&#xff0c;如何自定义泛型&…

记一次以小勃大,紧张刺激的渗透测试(2017年老文)

零、前言 有技术交流或渗透测试培训需求的朋友欢迎联系QQ/VX-547006660&#xff0c;需要代码审计、渗透测试、红蓝对抗网络安全相关业务可以看置顶博文 2000人网络安全交流群&#xff0c;欢迎大佬们来玩 群号820783253 一、起因 emmm&#xff0c;炎炎夏日到来&#xff0c;这…

libxlsxwriter数据验证

今天要分享的这个问题其实也属于excel的高级用法。我们想通过libxlsxwriter来实现一个能对用户的输入进行数据验证的表格功能。 内心os&#xff1a;小白最近是不是有点走火入魔了……我们真的会遇上这样的场景吗&#xff1a;需要通过代码生成一个表格&#xff0c;这个表格中还有…

智慧机场,或将成为航空领域数字孪生技术得完美应用

在《智慧民航建设路线图》文件中&#xff0c;民航局明确指出&#xff0c;智慧机场是实现智慧民航的四个核心抓手之一。这一战略性举措旨在推进数字化技术与航空产业的深度融合&#xff0c;为旅客提供更加智能化、便捷化、安全化的出行服务&#xff0c;进一步提升我国民航发展的…

IO流进阶

&#x1f3e1;个人主页 &#xff1a; 守夜人st &#x1f680;系列专栏&#xff1a;Java …持续更新中敬请关注… &#x1f649;博主简介&#xff1a;软件工程专业&#xff0c;在校学生&#xff0c;写博客是为了总结回顾一些所学知识点 目录IO流进阶缓冲流缓冲流概述字节缓冲流(…

【LeetCode】剑指 Offer(1)

目录 写在前面&#xff1a; 题目1&#xff1a;剑指 Offer 03. 数组中重复的数字 - 力扣&#xff08;Leetcode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 题目2&#xff1a;剑指 Offer 06. 从…

JavaEE初阶---TCP/IP协议

一:概述 本文是网络编程的理论基础,也是网络部分的重点和难点,在笔试,面试中,这部分内容也多有考察.二:详解 TCP/IP五层协议 应用层传输层网络层数据链路层物理层 2.1应用层 我们自己编写的代码,就是在应用层,这也是在实际开发中接触最多的层.应用层里有许多现成的协议 , 而在…