C++ Heap 堆的实现(最小堆&最大堆)

堆 heap

堆也叫优先队列,堆是一种特殊的完全二叉树数据结
堆分为两种,最大堆,最小堆。
最大堆:根节点大于左右两个子节点的完全二叉树
最小堆:根节点小于左右两个子节点的完全二叉树
堆可以用数组来存储,
a[i]处存根节点,a[2 * i]存左子树的根节点 ; a[2 * i + 1]存右子树的根节点。i从1开始!!
在这里插入图片描述

实现

 #pragma once
#include<vector>
//using namespace std;

enum heaptype
{
	MAXHEAP, MINHEAP,
};
template<class T>
class Myheap
{

private:
	std::vector<T>_vecdata;
	int _size;//元素数量
	int _capacity;//整个堆的大小
	heaptype _type;
public:
	Myheap(T data[],int len,heaptype);
	Myheap(int capacity, heaptype);//一个空堆
	virtual ~Myheap();
	bool push(T data);
	bool pop(int index);
	void print();
	bool full()
	{
		if (_size >= _capacity)
		{
			return true;
		}
		return false;
	}
	bool empty()
	{
		//检查的是堆是否为空而不是_capacity的大小
		return _size == 0;
	}

private:
	void _swap(int i, int j);
	
	//元素下沉
	void _sink(int index);
	//元素上浮
	void _floating(int index);
};
template <class T>
Myheap<T>::Myheap(T data[], int len, heaptype type):_size(0),_capacity(len),_type(type)
{
	_vecdata.resize(_capacity);
	//将data数组中元素加入堆中
	for (int i = 0; i < len; i++)
		push(data[i]);	
}
template <class T>
Myheap<T>::Myheap(int capacity, heaptype type):_size(0),_capacity(capacity), _type(type)   //创建一个capacity空间大小的空堆
{
	_vecdata.resize(_capacity);
}
template <class T>
Myheap<T>::~Myheap()
{
	//vector自动析构
}
template<class T>
bool Myheap<T>::push(T data)
{
	if (full()){
		throw("The heap is full !!\n");
		return false;
	}
	else 
	{
		_vecdata[_size] = data;
		++_size;
		_floating(_size);
		//将当期位置的数据进行判断上浮(这里的位置从1开始算,而非0)
		//这是为了更方便计算左结点和右结点的位置
		//当前节点: i   左结点: 2i  右结点: 2i+1
		return true;
	}
}
template<class T>
void Myheap<T>::_floating(int index)
{
	//只有一个元素&空堆不需要进行操作
	if (_size == 1)
		return;
	if (_type == MINHEAP)
	{
		for (int i = index; i > 0; i *= 0.5)
		{
			//小根堆的上浮
			//大根堆判断条件相反
			if (_vecdata[i - 1] < _vecdata[i*0.5 - 1])
				_swap(i - 1, i*0.5 - 1);
			else
				break;
		}
	}
	else if(_type==MAXHEAP)
	{
		for (int i = index; i > 0; i *= 0.5)
		{
			//大根堆的上浮
			if (_vecdata[i - 1] > _vecdata[i*0.5 - 1])
				_swap(i - 1, i*0.5 - 1);
			else
				break;
		}
	}
	return;
}
template<class T>
void Myheap<T>::_swap(int i, int j)
{
	T temp = _vecdata[i];
	_vecdata[i] = _vecdata[j];
	_vecdata[j] = temp;
	return ;
}
template<class T>
void Myheap<T>::_sink(int index)
{
	int i = index;
	if (_type == MINHEAP)
	{
		while (i * 2 <= _size)
		{
			//与左结点比
			if (_vecdata[i - 1] > _vecdata[i * 2 - 1])
			{
				_swap(i - 1, i * 2 - 1);
				//交换后,index位置的结点与其右结点比
				if (i * 2 + 1 <= _size && _vecdata[i - 1] > _vecdata[i * 2])
					_swap(i - 1, i * 2);
				i = i * 2;
			}
			//与右结点比
			else if (i * 2 + 1 <= _size && _vecdata[i - 1] > _vecdata[i * 2])
			{
				_swap(i - 1, i * 2);
				i = i * 2 + 1;
			}
			else
				break;
		}
	}
	else if (_type == MAXHEAP)
	{
		while (i * 2 <= _size)
		{
			//与左结点比
			if (_vecdata[i - 1] < _vecdata[i * 2 - 1])
			{
				_swap(i - 1, i * 2 - 1);
				//交换后,index位置的结点与其右结点比
				if (i * 2 + 1 <= _size && _vecdata[i - 1]< _vecdata[i * 2])
					_swap(i - 1, i * 2);
				i = i * 2;
			}
			//与右结点比
			else if (i * 2 + 1 <= _size && _vecdata[i - 1] < _vecdata[i * 2])
			{
				_swap(i - 1, i * 2);
				i = i * 2 + 1;
			}
			else
				break;
		}
	}
}
template<class T>
void Myheap<T>::print() {
	for (int i=0;i<_size;i++)
		std::cout << _vecdata[i]<< " ";
	std::cout << endl;
	return;
}
template<class T>
bool  Myheap<T>::pop(int index)
{
	if (empty())
	{
		throw("This is an empty heap !!\n");
		return false;
	}
	_vecdata[index] = _vecdata[_size - 1];
	--_size  ;
	_sink(index+1);
	return true;
}

测试

 //堆也叫优先队列,堆是一种特殊的完全二叉树数据结
//堆分为两种,最大堆,最小堆。
//最大堆:根节点大于左右两个子节点的完全二叉树
//最小堆:根节点小于左右两个子节点的完全二叉树
//堆可以用数组来存储,
//a[i]处存根节点,a[2 * i]存左子树的根节点 ; a[2 * i + 1]存右子树的根节点。i从1开始!!

#include<iostream>
#include"Myheap.h"

using namespace std;
int main() 
{
	int minheapbuffer[10] = { 9,8,7,6,5,4,3,2,1,0 };
	int maxheapbuffer[10] = { 0,1,2,3,4,5,6,7,8,9 };
	Myheap<int>minheap(minheapbuffer,10,MINHEAP);
	Myheap<int>maxheap(maxheapbuffer, 10,MAXHEAP);
	//小顶堆
	minheap.print();
	minheap.pop(1);
	minheap.print();
	minheap.push(1);
	minheap.print();
	cout << endl;
	//大顶堆
	maxheap.print();
	maxheap.pop(0);
	maxheap.print();
	maxheap.push(10);
	maxheap.print();
	system("pause");
	return 0;
}

在这里插入图片描述
代码:
https://github.com/ChristmasError/Data_Structure/tree/master/堆 Heap

猜你喜欢

转载自blog.csdn.net/qq_43265890/article/details/84671180