C++实现大根堆

一、堆的定义

堆的物理存储结构是一维数组,逻辑存储结构是完全二叉树。

堆的基本操作包括:insert–向堆中插入一个元素,deleteTop–删除堆顶元素
image
上面的图片就是一个大根堆,大根堆具有以下性质:每一个节点的值都小于它父节点的值。我们也可以从上面的图片中看出来。但是需要注意的是,每一个节点的值的大小与它所处的深度没有必然的联系

我们如果将这个最大堆存入数组中,就需要按照索引顺序存入:

0 1 2 3 4 5 6 7 8 9
60 40 29 31 27 16 14 25 15 26

公式如下:

当前节点的父节点 = (index - 1) / 2

当前节点的左子节点 = index * 2 + 1

当前节点的左子节点 = index * 2 + 2

二、如何实现一个堆

/*
*@大根堆的实现 
*@
*@
*@ 
*/
#include 
using namespace std;

class MaxHeap
{
public:
	int getsize()
	{
		return init_vec.size();
	}
	
	bool isEmpty()
	{
		return init_vec.empty();
	}
	
	int parent(int index)
	{
		if(index != 0)
		{
			return (index - 1)/2;
		}
	}
	
	int leftchild(int index)
	{
		return index*2 + 1;
	}
	
	int rightchild(int index)
	{
		return index*2 + 2;
	}
	
	//定义插入操作 
	void add(int num)
	{
		init_vec.push_back(num);
		siftUp(getsize() - 1);
	}
	
	//定义上浮操作
	void siftUp(int index)
	{
		while(index > 0 && init_vec[parent(index)] < init_vec[index])
		{
			swap(init_vec[parent(index)], init_vec[index]);
			index = parent(index);
		}
	}

	
	//定义下沉操作,每一个父节点的值都要大于子节点 
	void siftDown(int index) 
	{
		while(leftchild(index) < getsize())
		{
			int num = index;
			if(rightchild(index) < getsize())
			{
				if(init_vec[index * 2 + 1] < init_vec[index * 2 + 2])
				{
					num = index * 2 + 2;
				}
				else
					num = index * 2 + 1;
			} 
			else
			{
				num = index * 2 + 1;
			}
			swap(init_vec[index], init_vec[num]);
			index = num;
		} 
	}
	
	//返回最大元素,堆顶元素
	int findMax()
	{
		return init_vec[0];
	} 
	
	//取出堆顶,由于vector没有pop_front(),所以需将堆顶与最后一个元素交换,再pop_back(),再下沉
	int extractMax()
	{
		int ret = findMax();
		swap(init_vec[0],init_vec[getsize()-1]);
		init_vec.pop_back();
		siftDown(0);
		return ret;
	} 

	void swap(int &i,int &j)
	{
		int temp = i;
		i = j;
		j = temp;
	}
	
	
	vector init_vec;
	
}; 

int main()
{
	MaxHeap heap_0;
	heap_0.init_vec = {60, 40, 29, 31, 27, 16, 14, 25, 15, 26};
	heap_0.add(70);
	cout<

参考:数据结构------堆(二、堆的实现)

你可能感兴趣的:(算法)