堆的数据结构以及堆的相应操作

堆的定义

二叉树中的堆使用顺序存储的结构来进行存储这里的堆指代的是一种数据结构

在一个关键码存在的集合中K = {K1,K2,K3,....,Kn},把它的所有元素按照完全二叉树的顺序存储方式,存储在一个一维数组中,如果根结点的元素值大于其左右孩子的值,并且每个子树都满足这种情况,其对应的堆,我们称为最大堆

堆的相关操作

cpp 复制代码
//Heap.h

#pragma once
#include<iostream>
#include<stdlib.h>
#include<stdbool.h>
using namespace std;

#pragma region 定义堆的存储结构
typedef int HeapDataType;
/*定义哨兵*/
#define MAXDATA 0xfffff
typedef struct HNode* heap;
typedef heap MaxHeap;/*MaxHeap==Heap==HNode  所以MaxHeap是指针类型*/
typedef struct HNode
{
	HeapDataType* HeadData;/*指针用来指向数据存储的空间*/
	int sizes;/*当前堆的存储的数据的个数*/
	int capacity;/*堆所满足的最大的容量*/
};
#pragma endregion
/*堆的创建*/
MaxHeap/*此时实际上返回的是HNode*/ CreatHeap(int MaxSize);
/*堆的销毁*/
void DestoryHeap(MaxHeap M_hp);
/*堆的插入*/
MaxHeap InsertHeap(MaxHeap Mhp, HeapDataType* item);
/*堆的删除*/
MaxHeap DeleteHeap(MaxHeap Mhp);
/*创建最大堆*/
void MoveDown(MaxHeap Mhp, int length);
/*判断堆是否已满*/
bool IsFull(MaxHeap Mhp);

堆的具体实现的CPP程序

cpp 复制代码
#include"Heap.h"
/*创建具有MaxSize容量的最大堆*/
MaxHeap/*此时实际上返回的是HNode*/ CreatHeap(int MaxSize)
{
	MaxHeap Heap = NULL;
	Heap = (MaxHeap)malloc(sizeof(HNode));
	Heap->HeadData = (HeapDataType*)malloc(sizeof(HNode)*(MaxSize + 1));
	Heap->capacity = MaxSize;
	Heap->sizes = 0;
	Heap->HeadData[0] = MAXDATA;
	return Heap;
}
#pragma region 销毁最大堆
void DestoryHeap(MaxHeap Mhp)
{
	if (Mhp == NULL)
	{
		return;
	}
	delete[] Mhp->HeadData;
	Mhp->HeadData = NULL;
	Mhp->capacity = 0;
	Mhp->sizes = 0;
}
#pragma endregion
#pragma region 最大堆元素的插入
void SWAP(HeapDataType item_1, HeapDataType item_2)
{
	HeapDataType tmpstore;
	tmpstore = item_1;
	item_1 = item_2;
	item_2 = item_1;
}
MaxHeap InsertHeap(MaxHeap Mhp, HeapDataType* item)
{
	if (Mhp == NULL || item == NULL)
	{
		return false;/*输入的数据不符合要求*/
	}
	MaxHeap tmphp = NULL;
	tmphp = Mhp;
	/*判断是否满了*/
	if (tmphp->sizes == tmphp->capacity)
	{
		cout << "该堆结构存储空间已满" << endl;
		return false;
	}
	tmphp->HeadData[tmphp->sizes + 1] = *item;/*将元素首先放在尾部*/
	int childPos = tmphp->sizes + 1;
	int parentPos = childPos / 2;
	while (tmphp->HeadData[childPos] > tmphp->HeadData[parentPos])/*证明插入数据大于根节点的数据*/
	{
		SWAP(tmphp->HeadData[childPos], tmphp->HeadData[parentPos]);
		childPos = parentPos;
		parentPos = childPos / 2;
	}
	tmphp->sizes++;
	return tmphp;
}
#pragma endregion
#pragma region 最大堆元素的删除
MaxHeap DeleteHeap(MaxHeap Mhp)
{
	if (Mhp == NULL || Mhp->sizes == 0)
	{
		cout << "堆为空" << endl;
		return NULL;
	}
	MaxHeap tmphp = NULL;
	tmphp = Mhp;
	int parent = 1;
	int child = 2 * parent + 1;
	while (child<=tmphp->sizes)
	{
		if ((child+1<=tmphp->sizes)/*右孩子存在*/ && (tmphp->HeadData[child]<tmphp->HeadData[child+1]/*选择孩子中的最大一个*/) )
		{
			child = child + 1;/*先找到符合条件的child的位置*/
		}
		/*交换*/
		if (tmphp->HeadData[parent]<tmphp->HeadData[child])
		{
			SWAP(tmphp->HeadData[parent], tmphp->HeadData[child]);
			parent = child;
			child = 2 * parent + 1;
		}
		else
		{
			break;
		}
	}
	tmphp->sizes--;
	return tmphp;
}
#pragma endregion
#pragma region 创建最大堆
void MoveDown(MaxHeap Mhp, int length)
{
	if (Mhp == NULL || length == 0)
	{
		cout << "输入的堆的元素为空" << endl;
		return;
	}
	MaxHeap tmphp = NULL;
	tmphp = Mhp;
	int parent = length;
	int child = 2 * length + 1;
	while (child <=tmphp->sizes)/*防止左孩子出界*/
	{

		if ((child+1<=tmphp->sizes) && (tmphp->HeadData[child]<=tmphp->HeadData[child+1]))
		{
			/*右孩子更大*/
			child = child + 1;/*将更换的位置调整为右孩子*/
		}
		/*判断父结点位置的元素是否比孩子结点的小*/
		if (tmphp->HeadData[parent]<tmphp->HeadData[child])
		{
			SWAP(tmphp->HeadData[parent], tmphp->HeadData[child]);
			parent = child;
			child = 2 * parent + 1;
		}
		else
		{
			break;
		}
	}
}
MaxHeap CreatMaxHeap(MaxHeap Mhp)
{
	int length = Mhp->sizes/2;
	MaxHeap tmphp = NULL;
	tmphp = Mhp;
	/*首先找到具有最后一个结点的孩子*/
	for (length;length>0;length--)
	{
		MoveDown(tmphp, length);
	}
	return tmphp;
}
#pragma endregion
#pragma region 判断堆满情况
bool IsFull(MaxHeap Mhp)
{
	if (Mhp->sizes == Mhp->capacity)
	{
		return true;
	}
	return false;
}
#pragma endregion

这里需要明确:给定一组数据,利用大根堆的方式存储,具体步骤:

  • > 首先寻找到具有最后一个顺序存储的叶子结点的父亲结点,开始实现自后向前的遍历
  • > 遍历的每一个结点都实现基于大根堆的大数据向上移动而小数据向下move down的策略 。所以,有了一种针对每个结点都重复一次操作的实现过程。
相关推荐
m0_720245014 小时前
1543.统计好三元组(简单)
开发语言·算法
To_OC4 小时前
LC 560 和为 K 的子数组:前缀和配哈希表,这对组合我是真的服了
javascript·算法·程序员
hans汉斯5 小时前
《软件工程与应用》期刊推荐&10月版面征稿中
图像处理·人工智能·深度学习·算法·音视频·软件工程
叠层归一研究院5 小时前
AGI 系统(八):符号范畴嵌入函子 — SymCat ↪ C_M107 严格化
c语言·开发语言·人工智能·算法·transformer·agi
其美杰布-富贵-李6 小时前
08 进阶评估指标与算法特定指标
人工智能·算法
.道阻且长.7 小时前
5.LeetCode算法习题讲解--双指针--有效三角形的个数
算法·leetcode·职场和发展
我是海飞7 小时前
杰理JL703N SSD1306 OLED(128x64) 点阵屏移植说明
单片机·算法·嵌入式·音频·杰理
wabs6668 小时前
关于图论【最短路径之Bellman_ford 算法(单源有限最短路)|卡码网96.城市间货物运输III的思考】
数据结构·算法·图论·卡码网·bellman_ford·单源有限最短路
wuyk5559 小时前
2.队列:先进先出的线性数据结构
c语言·数据结构·stm32·单片机
lsylalalala10 小时前
常见的排序算法1
数据结构·算法·排序算法