最小堆是一种特殊的完全二叉树,优先队列往往就是用其来实现的。
这里简单实现了最小堆类模板的基本操作,并使用二叉树基础-实现堆结构(数据结构基础 第5周) 题目对其进行了测试。
源码
//test.cpp
#include <iostream>
#include "MinHeap.h"
using namespace std;
int main() {
int t=0;
cin >> t;
while(t--) {
int n=0;
cin >> n;
MinHeap<int> hp(n); //总共执行n次操作,堆容量置为n即可
while(n--) {
int a=0;
cin >> a;
if (a==1) {
int b=0;
cin >> b;
hp.Insert(b);
}
else if (a==2) {
int b=0;
hp.RemoveMin(b);
cout << b << endl;
}
}
}
return 0;
}
//MinHeap.h
#pragma once
template <class T>
class MinHeap
{
private:
T* heapArray; //存放堆数据的数组
int CurrentSize; //当前堆中的元素数目
int MaxSize; //最大元素数目
public:
MinHeap(const int n); //构造函数,参数n为堆的最大元素数目
virtual ~MinHeap() {delete []heapArray;}; //析构函数
bool isLeaf(int pos) const; //判断是否为叶节点
int leftchild(int pos) const; //返回左孩子位置
int rightchild(int pos) const; //返回右孩子位置
int parent(int pos) const; //返回父结点位置
bool Remove(int pos, T& node); //删除给定下标的元素, 返回其元素的值
bool RemoveMin(T& node); //从堆顶删除最小值
bool Insert(const T& newNode); //向堆中插入新元素
void SiftDown(int left); //从left开始向下筛选
void SiftUp(int position); //从position向上开始调整,使序列成为堆
};
template<class T>
MinHeap<T>::MinHeap(const int n)
{
if(n<=0)
return;
CurrentSize=0;
MaxSize=n;
heapArray=new T[MaxSize]; //创建堆空间
}
template<class T>
bool MinHeap<T>::isLeaf(int pos) const
{
return (pos>=CurrentSize/2)&&(pos<CurrentSize);
}
template<class T>
int MinHeap<T>::leftchild(int pos) const
{
return 2*pos+1; //返回左孩子位置
}
template<class T>
int MinHeap<T>::rightchild(int pos) const
{
return 2*pos+2; //返回右孩子位置
}
template<class T>
int MinHeap<T>::parent(int pos) const // 返回父节点位置
{
return (pos-1)/2;
}
template<class T>
void MinHeap<T>::SiftDown(int left)
{
int i=left; //标识父结点
int j=2*i+1; //标识关键值较小的子结点
T temp=heapArray[i]; //保存父结点
//过筛
while(j<CurrentSize)
{
if((j<CurrentSize-1)&&(heapArray[j]>heapArray[j+1]))
j++; //j指向右子结点
if(temp>heapArray[j])
{
heapArray[i]=heapArray[j];
i=j;
j=2*j+1;
}
else break;
}
heapArray[i]=temp;
}
template<class T>
void MinHeap<T>::SiftUp(int position)
{//从position向上开始调整,使序列成为堆
int temppos=position;
T temp=heapArray[temppos];
while((temppos>0)&&(heapArray[parent(temppos)]>temp))
{
heapArray[temppos]=heapArray[parent(temppos)];
temppos=parent(temppos);
}
heapArray[temppos]=temp;
}
template<class T>
bool MinHeap<T>::Remove(int pos, T& node) // 删除给定下标的元素, 返回其元素的值
{
if((pos<0)||(pos>=CurrentSize))
return false;
T temp=heapArray[pos];
heapArray[pos]=heapArray[--CurrentSize]; //用最后的元素代替被删除的元素
if (pos>0 && (heapArray[parent(pos)] > heapArray[pos]))
SiftUp(pos); //上升筛
else SiftDown(pos); //向下筛
node=temp;
return true;
}
template<class T>
bool MinHeap<T>::RemoveMin(T& node)
{
if(CurrentSize==0){
return false;
}
else{
node = heapArray[0];
heapArray[0]=heapArray[--CurrentSize]; //用最后的元素代替被删除的元素
if (CurrentSize>1) {
SiftDown(0);
}
return true;
}
}
template<class T>
bool MinHeap<T>::Insert(const T& newNode)
{//向堆中插入一个结点
if(CurrentSize>=MaxSize)
return false;
heapArray[CurrentSize]=newNode;
SiftUp(CurrentSize);
CurrentSize++;
return true;
}