数据结构——堆的实现(细)

news2024/11/25 23:33:20

目录

1.1 二叉树的顺序结构

普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段​编辑

1.2 堆的概念及应用

堆的性质:

堆中某个节点的值总是不大于或不小于其父节点的值;

堆总是一棵完全二叉树。

​编辑

​编辑如图所示就是小根堆和大根堆的展示 

2. 堆的代码及实现  

 2.1 向下调整和向上调整

这里面我们这期主要就讲解两种方法:向下调整,向上调整这两种方法

代码实现:


1.1 二叉树的顺序结构


普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段

 

1.2 堆的概念及应用

堆就是以二叉树的顺序存储方式来存储元素,同时又要满足父亲结点存储数据都要大于儿子结点存储数据(也可以是父亲结点数据都要小于儿子结点数据)的一种数据结构。堆只有两种即大堆和小堆,大堆就是父亲结点数据大于儿子结点数据,小堆则反之。

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


如图所示就是小根堆和大根堆的展示
 

2. 堆的代码及实现  

typedef int HPDataType;
typedef struct Heap
{
	HPDataType* a;
	int size;
	int capacity;
}HP;

void AdjustUp(HPDataType* a, int child);
void AdjustDown(int* a, int n, int parent);

void HeapInit(HP* php);
void HeapDestroy(HP* php);
void HeapPush(HP* php, HPDataType x);

void HeapPop(HP* php);
HPDataType HeapTop(HP* php);
bool HeapEmpty(HP* php);
int HeapSize(HP* php);

 2.1 向下调整和向上调整

这里面我们这期主要就讲解两种方法:向下调整,向上调整这两种方法

向下调整算法:作用就是通过从上到下的算法排序,将任意一个堆变成最小堆或者最大堆。

步骤:(此处以最小堆为例)
1、从根节点的左右孩子中选取一个较小值min
2、当前需要调整的数据与较小值min进行比较

  • 大于min:和min进行交换,从交换后的位置继续执行第1步;
  • 小于等于min:结束

 

void AdjustDown(HPDataType* a, int n, int parent)
{
	int child = parent * 2 + 1;
	while (child<n)
	{
		if (a[child + 1] > a[child])
		{
			child++;

		}
		if(a[child]>a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}

	}
}

向上调整:图解思路

 你每构建完一次小根堆,交换元素,你此时在数组上是不是把最小的元素放在末尾了,说明已经确定了,那我们就不需要动了,我们要动的就是数组那些没确定的元素,在这些里面去找一个最小的。那么这一步体现在堆上
举个例子,6,2.1.4 这么一组数我们第一次构建小根堆之后,1就跑到了堆顶,也就是跑到了数组首元素1,数组此时为1***,和最后一个元素交换,就成了** * 1,那么这个时候1就已经确定了,我们下来要做的是把**这三个构建出一个小根堆,这三个里最小的放在首元素
比方说是2** 1,我们交换2和这次没确定的数组最后一个元素,成了**21,此时2 和1已经确定了,我们再去剩下两个**去构建,去交换,最后得到 6 4 2 1

void AdjustDown(HPDataType* a, int n, int parent)
{
	int child = parent * 2 + 1;
	while (child<n)
	{
		if (a[child + 1] > a[child])
		{
			child++;

		}
		if(a[child]>a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}

	}
}


代码实现:

#include"Heap.h"
void HeapInit(HP* php)
{
	assert(php);
	php->a = NULL;
	php->size = 0;
	php->capacity = 0;
}

void HeapDestroy(HP* php)
{
	assert(php);
	free(php->a);
	php->a = NULL;

	php->size = 0;
	php->capacity = 0;
}

void HeapPush(HP* php, HPDataType x)
{
	assert(php);
	if (php->size == php->capacity)
	{
		int newCapacity = php->capacity == 0 ? 4 : php->capacity * 2;
		HPDataType* tmp = (HPDataType*)realloc(php->a, newCapacity * sizeof(HPDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		php->a = tmp;
		php->capacity = newCapacity;
	}
	php->a[php->size] = x;
	php->size++;

	AdjustUp(php->a, php->size - 1);

}

void Swap(HPDataType* p1, HPDataType* p2)
{
	HPDataType* tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

void AdjustUp(HPDataType* a, int 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;
		}
	}
}

void AdjustDown(HPDataType* a, int n, int parent)
{
	int child = parent * 2 + 1;
	while (child<n)
	{
		if (a[child + 1] > a[child])
		{
			child++;

		}
		if(a[child]>a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}

	}
}

void Heapop(HP* php)
{
	assert(php);
	assert(!HeapEmpty(php));

	Swap(&php->a[0], &php->a[php->size - 1]);
	php--;

	AdjustDown(php->a, php->size, 0);
}

HPDataType HeapTop(HP* php)
{
	assert(php);
	assert(!HeapEmpty(php));

	return php->a[0];
}

//
bool HeapEmpty(HP* php)
{
	assert(php);

	return php->size == 0;
}

int HeapSize(HP* php)
{
	assert(php);

	return php->size;

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

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

相关文章

Netty核心技术十--Netty 核心源码剖析

1. 基本说明 只有看过Netty源码&#xff0c;才能说是真的掌握了Netty框架。 在 io.netty.example 包下&#xff0c;有很多Netty源码案例&#xff0c;可以用来分析 2. netty 启动过程源码分析 本次分析使用的是example包下的echo 2.1 源码剖析的目的 用源码分析的方式走一下…

Java 动态规划 Leetcode 63. 不同路径 II

该题大部分思路可以根据Leetcode 62. 不同路径这篇博客了解 这里进行基于上面那篇博客后来对该题进行补充 代码展示&#xff1a; class Solution {public int uniquePathsWithObstacles(int[][] obstacleGrid) {int mobstacleGrid.length;int nobstacleGrid[0].length;//创建…

HDFS块详解

HDFS块详解 传统型分布式文件系统的缺点 现在想象一下这种情况&#xff1a;有四个文件 0.5TB的file1&#xff0c;1.2TB的file2&#xff0c;50GB的file3&#xff0c;100GB的file4&#xff1b;有7个服务器&#xff0c;每个服务器上有10个1TB的硬盘。 在存储方式上&#xff0c;我…

Docker安装ElasticSearch8.X docker安装elasticsearch8.X完整详细教程

Docker安装ElasticSearch8.X docker安装elasticsearch8.X完整详细教程 Docker 上安装 ElasticSearch 8.8.1 的步骤&#xff1a;选择要安装的ElasticSearch 版本1、拉取 ElasticSearch 镜像2、创建并运行容器关闭容器启动容器重启容器 3、elasticsearch常用端口以及作用4、测试&…

基于spring cloud alibaba的低代码核心工具,jvs-logic逻辑引擎

在现代企业管理中&#xff0c;决策扮演着至关重要的角色。然而&#xff0c;随着业务规模的扩大和数据量的增加&#xff0c;人工决策变得越来越困难和耗时&#xff0c;而且容易受到主观因素的影响。逻辑引擎的出现为企业提供了一种高效、准确的决策推理工具&#xff0c;能够以逻…

[工业互联-23]:EtherCat从站 - EtherCAT协议栈与工作原理, 软硬件解决方案

目录 第1章 EtherCAT通信原理 1.1 网络架构 1.2 分层模型 2.1 物理层 1.2 数据链路层 1.2.1 EtherCAT数据帧结构 1.2.2 EtherCAT报文寻址 第2章 EtherCAT从站 2.1 概述 2.2 EtherCAT从站的组成包括&#xff1a; 2.3 EtherCAT从站的硬件 2.4 从站控制信息芯片&#…

LeetCode[394]字符串解码

难度&#xff1a;Medium 题目&#xff1a; 给定一个经过编码的字符串&#xff0c;返回它解码后的字符串。 编码规则为: k[encoded_string]&#xff0c;表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的&#xff1b;…

【LeetCode热题100】打卡第34天:排序链表乘积最大的子数组

文章目录 【LeetCode热题100】打卡第34天&#xff1a;排序链表&乘积最大的子数组⛅前言 排序链表&#x1f512;题目&#x1f511;题解 乘积最大的子数组&#x1f512;题目&#x1f511;题解 【LeetCode热题100】打卡第34天&#xff1a;排序链表&乘积最大的子数组 ⛅前…

如何将文字转化为语音?三个方法帮你轻松实现!

如何将文字转化为语音&#xff1f;在工作或学习中&#xff0c;我们可能会遇到需要将文字转化为语音的情况&#xff0c;这可能会让一些人感到困惑&#xff0c;不知道如何实现这个转换。其实&#xff0c;只需要利用一些第三方工具&#xff0c;就可以轻松地将文字转化为语音。下面…

十四、flex弹性容器属性样式2

目录&#xff1a; 1.准备工作 2.属性解析&#xff1a; align-items 3.属性解析&#xff1a; align-content 4.弹性元素的属性 一、准备工作 我们在前面的基础上&#xff0c;修改代码&#xff0c;把ul的高度定下来&#xff0c;设置800px, li的高度不定。 然后&#xff0c;body里…

音频采样器 Native Instruments Kontakt7 forMac/Windows图文安装教程

Native Instruments Kontakt是一款功能强大、灵活易用的音乐采样软件&#xff0c;适用于各种音乐创作和制作需求。无论是专业音乐制作人还是初学者&#xff0c;都能通过它来实现创意的音乐作品。 Kontakt具有直观的用户界面&#xff0c;可通过拖放方式导入和管理采样库。它支持…

Vmware虚拟机网络配置回顾

如何配置Vmware里的虚拟机网络&#xff1f;这个东西不常用&#xff0c;都是自己练手用的。能用就行&#xff0c;千万不要花时间记&#xff0c;没意义。 很简单&#xff0c;照着敲 首先登陆自己的虚拟机 vim /etc/sysconfig/network-scripts/ifcfg-ens32 TYPE"Ethernet&q…

数据结构--并查集

数据结构–并查集 逻辑结构―—“集合” 所有元素的全集s 将各个元素划分为若干个互不相交的子集 用互不相交的树&#xff0c;表示多个“集合” “并查集”的存储结构 用一个数组S[ ]即可表示“集合”关系 ‘并查集”的基本操作 集合的两个基本操作―— “并” \color{red}“…

ios14~14.3越狱/root(Taurine牛磺酸1.1.6)

Taurine牛磺酸 一键完美越狱 windows安装时建议关闭本地安全中心&#xff08;若报毒的话&#xff0c;没有则忽略&#xff09; 1.安装windows端AltInstaller&#xff1a;安装成功后&#xff0c;电脑右下角控制中心有一个&#xff08;灰色的 小方块&#xff09; 2.安装手机端A…

layui入门

layui入门 一.ayui简介1.简单易用2.组件丰富3.高度定制化4.响应式布局5.轻量灵活 2.layui的入门基础操作3.登录实例4.注册实例 一.ayui简介 Layui&#xff08;流行音 “layui”&#xff0c;来自“领域的模块化”&#xff09;是一款前端UI框架&#xff0c;专注于提升 Web 开发效…

Jmeter接口关联(三)【使用正则表达式提取值】以及正则表达式提取器中模板的含义及用法

文章目录 前言一、Jmeter中使用正则表达式匹配 1、选择 RegExp Tester2、在线程组------》添加------》后置处理器-------里面添加一个“正则表达式提取器”二、关于正则表达式提取器里面字段的解释 参数说明三、进一步解释Jmeter正则表达式提取器中的模板 1、当模板设置为$0$ …

每个开发人员都应该知道的VS Code入门技巧

这里有一些每个开发人员都应该知道的关于Visual Studio Code (VS Code)的技巧: 1、自定义键盘快捷键:VS Code允许您根据自己的喜好自定义键盘快捷键。点击“文件”->“首选项”->“键盘快捷键”或使用快捷键Ctrl K和Ctrl S打开键盘快捷键编辑器。可以修改现有快捷方式或…

抖音seo源码打包分享

抖音seo源码搭建----分享给各位开发者 获取视频列表 $Video_model new App_Model_Douyin_MysqlVideoStorage(); $video_list $Video_model->getList($where,$this->index,$this->count,$sort); $temp_video_model new App_Model_Douyin_…

微信小程序input的placeholder脱离文档流

今天进行真机调试时input的提示词 placeholder脱离了文档流&#xff0c;但是奇怪的是input框没有脱离文档流 如下图所示&#xff1a; 微信开发工具正常&#xff1a; 真机&#xff1a;不正常 脱离文档流 解决方法&#xff1a; <view clas…

给一个体积水,用不同体积的容器去装

这个有两个方案&#xff1a; 1.每个都装得最满&#xff0c;减少瓶子容积损失 //xzlist 瓶子容积排序 tj水总体积 xzzc各个体积瓶子数 public static void Boxjs(int tj, List<Map<String,Object>> xzlist, List<Map<String,Object>> xzzc){boolean f…