【数据结构C++】最大堆最小堆的实现

本文详细阐述了在学习数据结构过程中实现最大堆的注意事项,包括完全二叉树特性、哨兵元素使用、上滤操作的应用,以及通过实例展示了如何正确构造、插入和删除元素。通过测试代码和结果,揭示了可能遇到的错误和解决方案。
摘要由CSDN通过智能技术生成

数据结构学习过程中,了解了最大堆最小堆的知识,现自己根据理解实现了最大堆。
对于实现最大最小堆,我总结了以下我可能会犯错的几点:
1、最大最小堆利用完全二叉树来实现,注意完全二叉树的左对齐性质,还有所有子节点均小于(或大于)父节点的性质;
2、实现用到的数组,0位置不存放需要插入的元素,在0位置放置一个极大值(或极小值),可以充当哨兵作用。如果0位置放置了需要插入的元素,则会影响父子节点之间位置关系的运算,不满足parent = child / 2,给操作带来麻烦;
3、注意理解上滤概念,理解上滤在插入和删除中的用法。

以下是实现和测试过程,最小堆的实现与最大堆基本一致,改变判别条件即可:

.h文件

typedef int ElemType;
#define FALSE 1000000  //用作0位置存储值,也用作删除判断

class MaxHeap {
public:
	//默认构造函数
	MaxHeap();
	//有参构造函数
	MaxHeap(int max);   

	//析构函数
	~MaxHeap();  

	//1、判断是否为空
	bool IsEmpty();

	//2、判断是否已满
	bool IsFull();

	//3、插入元素
	bool Insert(ElemType x);

	//4、删除最大元素
	ElemType DeleteMax();

	//打印测试
	void printHeap();

	
private:
	ElemType* Heap;    //堆数组头指针
	int MaxSize;    //堆的最大容量
	int HeapSize;      //堆的大小
};

.cpp文件

//默认构造函数,默认堆的大小为100
MaxHeap::MaxHeap() {
	this->MaxSize = 100;
	
	//因为0位置不放元素,所以申请101个空间
	this->Heap = new ElemType[101];
	this->HeapSize = 0;
	
	this->Heap[0] = FALSE;
}
//有参构造函数,参数为堆的最大容量
MaxHeap::MaxHeap(int max) {
	this->MaxSize = max;
	this->Heap = new ElemType[max + 1];
	this->HeapSize = 0;

	this->Heap[0] = FALSE;
}

MaxHeap::~MaxHeap() {
	delete[] Heap;
}

//1、判断是否为空
bool MaxHeap::IsEmpty() {
	if (this->HeapSize == 0) return true;
	return false;
}

//2、判断是否已满
bool MaxHeap::IsFull() {
	if (this->HeapSize == this->MaxSize) return true;

	return false;
}

//3、插入元素
bool MaxHeap::Insert(ElemType x) {
	//如果堆已满,插入失败
	if (IsFull()) {
		cout << "堆已满" << endl;
		return false;
	}

	//先将要插入元素放入空穴中
	this->HeapSize++;  //大小加1,方便下面创建空穴
	this->Heap[this->HeapSize] = x;  //先将插入元素存入空穴
	
	//上滤替换到一个合适位置
	for (int i = this->HeapSize; x > this->Heap[i/2]; i = i / 2) {
		ElemType temp = this->Heap[i/2];
		this->Heap[i / 2] = this->Heap[i];
		this->Heap[i] = temp;
	}
	return true;
}

//4、删除元素
ElemType MaxHeap::DeleteMax() {
	//如果堆为空,返回0位置最大值
	if (IsEmpty()) return  FALSE;

	//将最大元素取出,最后返回
	ElemType Max = this->Heap[1];

	//最大值位置处放入最后一个节点元素,然后逐步向下过滤,找到合适位置
	this->Heap[1] = this->Heap[this->HeapSize];
	this->HeapSize--;  //逻辑删除

	//进行逐步过滤
	int child;
	for (int i = 1; i * 2 < this->HeapSize; i = child) {

		//先找到两个子节点中更大的那个位置
		if (i * 2 != this->HeapSize && this->Heap[i * 2] < this->Heap[i * 2 + 1])
			child = i * 2 + 1;
		else
			child = i * 2;

		//如果该元素小于两个子节点中最大值,进行交换
		if (this->Heap[i] < this->Heap[child]) {
			ElemType temp = this->Heap[i];
			this->Heap[i] = this->Heap[child];
			this->Heap[child] = temp;
		}
		else break;  //如果不小于,说明位置合适,终止循环
	}

	return Max;
}

//打印测试
void MaxHeap::printHeap() {
	for (int i = 1; i <= this->HeapSize; i++)
	{
		cout << this->Heap[i] << " ";
	}
	cout << endl;
}

测试代码:

int main() {

	MaxHeap heap(50);

	heap.Insert(10);
	heap.Insert(23);
	heap.Insert(20);
	heap.Insert(9);
	heap.Insert(15);
	heap.printHeap();
	
	while (!heap.IsEmpty()) {
		heap.DeleteMax();
		heap.printHeap();
	}
	
	return 0;
}

测试结果:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值