堆的基本操作,堆排序(C语言实现)初始化,插入,删除,销毁,排序

news2024/10/7 12:23:01

文章目录

  • 前言
  • 一、堆的基本变量
  • 二、堆的基本操作
    • 2.1堆的初始化(HeapInit)
    • 2.2堆的销毁(HeapDestroy)
    • 2.3向上调整(AdjustUp)
    • 2.4向下调整(AdjustDown)
    • 2.45堆是否为空(HeapEmpty)
    • 2.5堆的插入(HeapPush)
    • 2.6堆的删除(HeapPop)
    • 2.7堆的首元素(HeapTop)
    • 2.8堆的大小(HeapSize)
  • 三、堆排序
    • 3.1把给的数据建成一个堆
    • 3.2堆排序Heapsort


前言

完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

堆的性质:
堆中某个节点的值总是不大于或不小于其父节点的值;
堆总是一棵完全二叉树。

在这里插入图片描述


一、堆的基本变量

typedef int HPDataType;//堆的数据类型
typedef struct Heap {
	HPDataType* a;//堆所指向空间地址
	int size;//当前容量
	int capacity;//最大容积
}HP;//结构体用来存放堆与堆的一些基本变量

二、堆的基本操作

2.1堆的初始化(HeapInit)

void HeapInit(HP* php) {
	assert(php);
	//堆是可以为空的,但是php是结构体
	//里面除了含有堆还有堆的基本量,
	//基本量不能为NULL
	//当堆为空,php不能为空,因为php-》size=0为有效值
	//所以需要断言php是否为空
	php->a = (HPDataType*)malloc(sizeof(HPDataType) * 4);
	//申请四个大小
	if (php->a == NULL) {
		perror("malloc");
		return;
	}//判断申请的空间是否为空
	php->size = 0;//初始大小为0
	php->capacity = 4;//最大容量为4
}

2.2堆的销毁(HeapDestroy)

void HeapDestroy(HP* php) {
	assert(php);
	free(php->a);
	//释放堆的空间
	php->a = NULL;
	php->capacity = php->size = 0;
	//容量与大小变为0
}

2.3向上调整(AdjustUp)

在这里插入图片描述
在这里插入图片描述

void AdjustUp(HPDataType* a, int child) {//这里我们以建大堆为例
	//向上调整条件:
	// 除了child这个位置前面的数据构成堆
	
	//大堆要父母比孩子大
	int parent = (child - 1) / 2;
	//父母的下标
	while (child > 0) {
		if (a[child] > a[parent]) {
			//孩子比父母大交换
			Swap(&a[child], &a[parent]);
			child = parent;
			//接着向上
			parent = (child - 1) / 2;
		}
		else{
			break;
		}
	}
}

2.4向下调整(AdjustDown)


图中是在建小堆,但我们代码以大堆为例,除了大于小于的方向不同,但逻辑是一样的

void AdjustDown(HPDataType* 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{
			break;
		}
	}
}

2.45堆是否为空(HeapEmpty)

bool HeapEmpty(HP* php) {
	assert(php);
	return php->size == 0;
	//为0返回true否则返回false
}

2.5堆的插入(HeapPush)

在这里插入图片描述
图片是小堆,我们代码是大堆

void HeapPush(HP* php, HPDataType x) {
	assert(php);
	if (php->size == php->capacity) {//判断容量是否够用
		//不够用则进行扩容
		HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * (php->capacity) * 2);
		if (tmp == NULL) {
			perror("realloc");
			return;
		}
		//判断新的空间地址是否为空
		php->a = tmp;//把新容量的地址给我们堆
		php->capacity *= 2;
		//容量别忘了改
	}
	php->a[php->size] = x;//插入在最后
	php->size++;
	//当前大小加一
	AdjustUp(php->a, php->size-1);
	//从新的元素下标位置向上调整让他回到正确位置
}

2.6堆的删除(HeapPop)

在这里插入图片描述
图片是小堆,代码是大堆

void HeapPop(HP* php) {
	assert(php);
	assert(!HeapEmpty(php));
	//判断是否大小为空
	Swap(&php->a[0], &php->a[php->size - 1]);
	//交换第一个与最后一个数据
	php->size--;//大小减一
	AdjustDown(php->a, php->size, 0);
	//从第一个数据位置向下调整
	//让其回到其正确位置
}

2.7堆的首元素(HeapTop)

HPDataType HeapTop(HP* php) {
	assert(php);
	assert(!HeapEmpty(php));
	return php->a[0];
}

2.8堆的大小(HeapSize)

int HeapSize(HP* php) {
	assert(php);
	return php->size;
}

`

三、堆排序

3.1把给的数据建成一个堆

1.向上建堆,时间复杂度为O(N*logN)

 for (int i = 1; i < size; i++) {
		AdjustUp(a, i);
	} 
	 //因为向上建堆的要求除了child位置其余位置构成堆
	 //所以我们只能从第二个数据开始调整,
	 //前两个数据构成堆我们再从第三个数据开始调整
	 //以此类推直到下标为size-1

2.向下建堆,时间复杂度为O(N)推荐!!!

for ( int i = (size - 1 - 1) / 2; i >= 0; i--) {
		//i刚开始为下标为(size-1)的父母
		AdjustDown(a, size, i);
	} 
	//向下调整条件左右都为堆,
	//所以我们从下开始调整,小范围到大范围
	//先把小范围都变成堆,然后逐渐扩大每次调整的数据个数
	//倒数从第一个非叶结点开始调整

3.2堆排序Heapsort

在这里插入图片描述

void HeapSort(int* a, int size) {
	for ( int i = (size - 1 - 1) / 2; i >= 0; i--) {
		//i刚开始为下标为(size-1)的父母
		AdjustDown(a, size, i);
	} 
	//向下调整条件左右都为堆,
	//所以我们从下开始调整,小范围到大范围
	//先把小范围都变成堆,然后逐渐扩大每次调整的数据个数
	//倒数从第一个非叶结点开始调整

	//要升序则要建大堆
	//要排成降序则要建小堆
	int end = size - 1;//最后一个元素下标为end
	while (end > 0) {
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
		end--;
		//排好一次正确位置end要减一
	}
}

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

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

相关文章

JAVA springboot创业实践学分管理系统idea开发mysql数据库web结构计算机java编程MVC

一、源码特点 idea springboot创业实践学分管理系统是一套完善的web设计系统mysql数据库MVC模式开发&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式 开发。 JAVA springboot创业实践学分管理系统ide…

英语语法第一章之英语语法综述

英语的任何句型基本都可以翻译成 什么怎么样 &#xff0c;在这里什么就是我们常说的主语&#xff0c;而怎么样就是我们常说的谓语; 可能有些小伙伴会反问&#xff0c;不是主谓宾吗&#xff1f;别急等我慢慢讲解 在这里谓语也有很有多的不同的动作 可以独立完成的动作 句型&am…

交叉编译eigen 到hi3559

3559操作自记录 0502 ubuntu 操作日志 sudo apt-get install cmake-qt-gui whereis aarch64-himix100-linux-gcc aarch64-himix100-linux-gcc: /opt/hisi-linux/x86-arm/aarch64-himix100-linux/bin/aarch64-himix100-linux-gcc 然后把同级的gnu放进来了&#xff0c;然后confi…

Packet Tracer - 交换机端口安全故障排除

Packet Tracer - 交换机端口安全故障排除 场景 通常使用 PC1 的员工将家里的笔记本电脑带来&#xff0c;然后断开 PC1 的连接并将笔记本电脑连接到电信插座。 在提醒此安全策略不支持在网络上使用个人设备后&#xff0c;您必须重新连接 PC1 并重新启用端口。 拓扑图 要求 …

菜鸡shader:L1基于兰伯特原理的玉石材质

这里就简单说下原理吧&#xff0c;使用unity很久之前的一个插件shaderforge&#xff0c;最近几年好像在unity资源商店已经不再维护了&#xff0c;但是有shader forge的官网&#xff1a;在这&#xff0c;碰到节点不会的时候可以查一下官方文档&#xff0c;还是很方便的&#xff…

方舟开服教程——开服服务器配置选择及租用建议指导

目前方舟开服有以下服务器模式可以选择&#xff1a; 1、自己家里的设备或物理机放家里开 2、自己购服务器设备托管到机房 3、租独立物理机 4、租虚拟机 5、租云服务器 6、淘宝面板服 配置如何选择 一般每一个地图4G可以运行&#xff08;使用内存清理压缩内存但会性能损失容易卡…

【工具使用】STM32CubeMX-Uart配置 及 数据收发功能实现

一、概述 无论是新手还是大佬&#xff0c;基于STM32单片机的开发&#xff0c;使用STM32CubeMX都是可以极大提升开发效率的&#xff0c;并且其界面化的开发&#xff0c;也大大降低了新手对STM32单片机的开发门槛。     本文主要讲述STM32芯片的Uart的配置及其相关知识。Uart…

Ubuntu使用gzip与bzip2与rar和tar压缩解压

目录 1、gzip压缩解压 2、bzip2压缩解压 3、rar压缩解压 tar归档压缩与解压包 1、gzip压缩解压 因为都是系统自带的我们不需要安装&#xff1b; ls 看一下目录当前的文件&#xff0c;创建一个 touch 123.txt 文件&#xff1b; gzip 进行压缩&#xff0c;&#xff08;“ …

【BMS】电池能量管理:充电管理

&#x1f50b; 电池包能量管理&#xff1a;充电管理 &#x1f50b; 一、通信 充电是一个过程&#xff0c;需要电池包和充电器间进行频繁的通信&#xff0c;以保证电池安全和寿命。由于通信速率要求不高&#xff0c;以及精简接口的考虑&#xff0c;通常采用GPIO自定义单线通信…

Redis高级——批处理优化

2、批处理优化 2.1、Pipeline 2.1.1、我们的客户端与redis服务器是这样交互的 单个命令的执行流程 N条命令的执行流程 redis处理指令是很快的&#xff0c;主要花费的时候在于网络传输。于是乎很容易想到将多条指令批量的传输给redis 2.1.2、MSet Redis提供了很多Mxxx这样的…

【vueCms】vueCms_xg后台管理系统(开源)

我的开源项目地址:vueCms_xg &#x1f3ae;在线体验 开发文档&#xff1a;制作中后台地址&#xff1a;vueCms_xg(域名审核中) ⚡️ 简介 一个开箱即用&#xff0c;前端基于 vite 2 vue 3 typeScript element Plus pinia vue-router 4 的PC端项目模板。 后端由nestjs构…

浅谈osgViewer::StatsHandler、osg::Stats类的用法

目录 1. 前言 2. osgViewer::StatsHandler 2.1. 功能与用法说明 2.2. 主要接口说明 3. osg::Stats 1. 前言 osg为视景器的使用和调试提供了丰富的辅助组件&#xff0c;它们主要是以osg::ViewerBase的成员变量或交互事件处理器(osgGA::GUIEventHandler)的形式出现。osgView…

Linux线程:死锁

1. 死锁 &#xff08;1&#xff09;概念 死锁&#xff08;DeadLock&#xff09;指两个或两个以上的进程或线程执行时&#xff0c;由于竞争临界资源而造成阻塞的现象&#xff1b;若不干涉&#xff0c;则无法推进下去。 &#xff08;2&#xff09;死锁的原因 ① 竞争临界资源…

商业运营级Java定位系统源代码

智慧工厂人员定位系统源码 技术架构&#xff1a;Java vue spring boot 系统概述&#xff1a; 采用UWB定位技术&#xff0c;通过在厂区内布设一定数量的定位基站&#xff0c;实时精确地定位员工、车辆、物品上微标签位置&#xff0c;零延时地将人、车、物的位置信息显示在工厂…

8年测试老鸟谈,性能测试-测试环境搭建与常见问题,这些你都知道吗?

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 一个问题&#xf…

千模大战鏖战正酣,大模型能否帮360重回巅峰?

ChatGPT问世后&#xff0c;互联网终于看到了变革的曙光。 回望互联网的征程&#xff0c;几乎每十年左右&#xff0c;就会因产品和技术的变革&#xff0c;而催生出全新的应用场景。 00年代&#xff0c;随着PC产品的逐渐成熟&#xff0c;桌面互联网成为时代的“主旋律”。在此背…

ChatGPT提示词工程(七):Chatbot聊天机器人

目录 一、说明二、安装环境1. 辅助函数&#xff1a;get_completion2. 辅助函数&#xff1a;get_completion_from_messages 三、聊天机器人&#xff08;Chatbot&#xff09;1. 一般聊天机器人1.1 简单的例子1.2 多轮对话 2. 订单机器人 一、说明 这是吴恩达 《ChatGPT Prompt E…

Jackson使用详解

Spring MVC 默认采用Jackson解析Json&#xff0c;尽管还有一些其它同样优秀的json解析工具&#xff0c;例如Fast Json、GSON&#xff0c;但是出于最小依赖的考虑&#xff0c;也许Json解析第一选择就应该是Jackson。 一、简介 Jackson 是当前用的比较广泛的&#xff0c;用来序…

【Spring框架全系列】第一个Spring程序

&#x1f3d9;哈喽&#xff0c;大家好&#xff0c;我是小浪。那么从今天开始&#xff0c;我就要开始更新spring框架全系列的博客了&#xff1b;本专栏免费阅读&#xff0c;最好能够点个订阅&#xff0c;以便于后续及时收到更新信息哈&#xff01;&#x1f3df; &#x1f4f2;目…

【Java EE 初阶】线程的常用方法

目录 1.多线程的作用 2.示例&#xff1a;分别对两个变量实现10亿次自增 1.使用串行&#xff08;单线程&#xff09; 2.使用并行&#xff08;多线程&#xff09; 结果显示&#xff1a; 3.线程的类构造方法 代码展示&#xff1a; 4.Thread类的常见属性 1.演示各个属性 2.演…