二叉堆的c++实现

/************************************************************************
    > File Name: BinaryHeap.cpp
    > Author: wpf
    > Mail: wpf9264@163.com 
    > Created Time: 2019年03月04日 星期一 16时42分52秒
************************************************************************/

#include<iostream>
#include <vector>
#include "dsexceptions.h"
using namespace std;

template<typename Comparable>
class BinaryHeap
{
	private:
		int currentSize;
		vector<Comparable>	array;

		void buildHeap()
		{
			for(int i=currentSize/2; i>0; --i)
				percolateDown(i);
		}
		void percolateDown(int hole)
		{
			int child;
			Comparable tmp = std::move(array[hole]);//将要下滤的元素保存下来
			for( ; hole*2 <= currentSize; hole = child)
			{
				//说明该节点有孩子
				child = hole*2;
				//找到儿子中的最小值,准备上移
				if(child != currentSize && array[child+1] < array[child])
					++child;
				if(array[child] < tmp)
					array[hole] = array[child];
				else
					break;	
			}
			array[hole] = std::move(tmp);

		}


	public:
		//capacity+1 是为了处理默认输入capacity=0时的情况
		explicit BinaryHeap(int capacity = 100):array(capacity + 1),currentSize{0}
		{ }
		//这里要对item.size()进行格式转换,不然会警告narrowing conversion
		explicit BinaryHeap(const vector<Comparable> & item):array(item.size()+10),currentSize{int(item.size())}
		{
			for(int i=0; i<item.size(); ++i)
				array[i+1] = item[i];
			buildHeap();
		}

		bool isEmpty()const
		{ return currentSize==0; }

		const Comparable & findMin()const
		{
			if(isEmpty())
				throw UnderflowException{};
			return array[1];
		}

		void insert(const Comparable & x)
		{
			//堆内部的数组不够用了,现在进行扩容
			if(currentSize == array.size()-1)
				array.resize(array.size()*2);
			//建立一个空穴,并保存要插入的值
			int hole = ++currentSize;
			//下面这句也可以去掉,直接令array[0]=std::move(x)
			Comparable copy = std::move(x);			//这里为什么非要加一个copy呢,直接用x给array[0]赋值不就行了

			//开始上滤
			array[0] = std::move(copy);
			for( ; x<array[hole/2]; hole/=2)
				array[hole] = std::move(array[hole/2]);//父节点下移
			array[hole] = std::move(array[0]);

		}
		void insert(Comparable && x)
		{
			//堆内部的数组不够用了,现在进行扩容
			if(currentSize == array.size()-1)
				array.resize(array.size()*2);
			//建立一个空穴,并保存要插入的值
			int hole = ++currentSize;
			for( ;hole>1 && x<array[hole/2]; hole/=2)
				array[hole] = std::move(array[hole/2]);//父节点下移
			array[hole] = std::move(x);

		}
		void deleteMin()
		{
			if(isEmpty())
				throw UnderflowException{};
			array[1] = std::move(array[currentSize--]);
			percolateDown(1);
		}
		//删除最小项,并将其放在minItem
		void deleteMin(Comparable & minItem)
		{
			if(isEmpty())
				throw UnderflowException{};
			minItem = std::move(array[1]);
			array[1] = std::move(array[currentSize--]);
			percolateDown(1);
		}
		void makeEmpty()
		{
			currentSize= 0;
		}

};






int main(int argc,char** argv)
{
	BinaryHeap<int> v;
	cout<<"isEmpty()= "<<v.isEmpty()<<endl;
	v.insert(8);
	v.insert(2);
	v.insert(0);
	v.insert(6);
	v.insert(9);
	v.insert(7);
	v.insert(4);
	v.insert(3);
	cout<<"isEmpty()= "<<v.isEmpty()<<endl;
	int a;
	v.deleteMin(a);
	cout<<"min():     "<<a<<endl;
	v.deleteMin(a);
	cout<<"min():     "<<a<<endl;
	v.deleteMin(a);
	cout<<"min():     "<<a<<endl;
	v.makeEmpty();
	cout<<"isEmpty()= "<<v.isEmpty()<<endl;



	vector<int> dd{8,2,0,6,9,7,4,3};
	BinaryHeap<int> t{dd};
	cout<<"isEmpty()= "<<t.isEmpty()<<endl;
	t.deleteMin(a);
	cout<<"min():     "<<a<<endl;
	t.deleteMin(a);
	cout<<"min():     "<<a<<endl;
	t.deleteMin(a);
	cout<<"min():     "<<a<<endl;
	t.makeEmpty();
	cout<<"isEmpty()= "<<t.isEmpty()<<endl;
	return 0;
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值