建堆

堆数据结构是一种数组对象,它可以被视为一颗完全二叉树结构

堆结构的二叉树存储是:

最大堆:每个父节点都大于孩子结点

最小堆:每个父节点都小于孩子结点

vector<int>_arr:创建vector对象,使得数组不是一个确定的大小,当其需要增大容量时会自动增大

代码中用到了向下调整和向上调整的思想

#include<iostream>
#include<vector>
using namespace std;
template<class T>
class Heap
{
public:
	Heap(T* arr,size_t size)
	{
		_arr.reserve(size);//_arr的初始化
		for(size_t i=0;i<size;i++)
		{
			_arr.push_back(arr[i]);//把arr同样的给_arr
		}
		for(int i=(_arr.size()-2)/2;i>=0;--i)//从最后一个非叶子结点开始,数组建堆
		{
			AdjustDown(i);
		}
	}
	void push(const T& data)//在堆里面插入一个元素
	{
		_arr.push_back(data);
		AdjustUp(_arr.size()-1);
	}
	void pop()//pop堆顶的元素
	{
		swap(_arr[0],_arr[_arr.size()-1]);//堆顶元素和最后一个元素交换
		_arr.pop_back();//pop掉最后一个元素
		AdjustDown(0);
	}
	void Display()
	{
		  for(size_t i=0;i<_arr.size();i++)
		  {
			  cout<<_arr[i]<<" ";
		  }
		  cout<<endl;
	}
	void AdjustDown(size_t root)
	{
		size_t parent=root;
		size_t child=2*parent+1;
		while(child<_arr.size())
		{
			if(child+1<_arr.size()&&_arr[child+1]>_arr[child])
			{
				++child;
			}
			if(_arr[child]>_arr[parent])
			{
				swap(_arr[child],_arr[parent]);
				parent=child;
				child=2*parent+1;
			}
			else
			{
				break;
			}
		}
	}
	void AdjustUp(size_t root)
	{
		size_t child=root;
		size_t parent=(child-1)/2;
		while(parent>=0)
		{
			if(_arr[child]>_arr[parent])
			{
				swap(_arr[child],_arr[parent]);
				child=parent;
				parent=(child-1)/2;
			}
			else
			{
				break;
			}
		}
	}
	size_t Size()
	{
		return _arr.size();
	}
	bool Empty()
	{
		return _arr.empty();
	}
	const T& Top()
	{
		return _arr[0];
	}
private:
	vector<T>_arr;//vector 就相当于类中的一个自定义类型的数组

};
void test()
{
	int arr[]={10,16,18,12,11,13,15,17,14,19};
	int size=sizeof(arr)/sizeof(arr[0]);
	Heap<int> hp(arr,size);//声明类后,定义了一个对象;
	hp.Display();
	hp.push(20);
	hp.Display();
	hp.pop();
	hp.Display();
	cout<<"size="<<hp.Size()<<endl;
	cout<<"empty ?"<<hp.Empty()<<endl;
	cout<<"top="<<hp.Top()<<endl;
}
int main()
{
	test();
	system("pause");
	return 0;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值