大顶堆

MaxHeap.h

#ifndef _MAX_HEAP_
#define _MAX_HEAP_

template <class T>
class MaxHeap
{
public:
	MaxHeap(int mx = 10);
	virtual ~MaxHeap();

	bool IsEmpty();
	void Push(const T&);
	void Pop();
	const T& Top() const;
private:
	T* heapArray;
	int maxSize;
	int currentSize;

	void trickleUp(int index);
	void trickleDown(int index);
};

template <class T>
MaxHeap<T>::MaxHeap(int mx = 10)
{
	if (mx<1) throw "max size must be >= 1.";

	maxSize = mx;
	currentSize = 0;
	heapArray = new T[maxSize];
}

template <class T>
MaxHeap<T>::~MaxHeap()
{
	delete[] heapArray;
}

template <class T>
bool MaxHeap<T>::IsEmpty()
{
	return currentSize == 0;
}

template <class T>
void MaxHeap<T>::Push(const T& e)
{
	if (currentSize == maxSize) throw "MaxHeap is full.";

	heapArray[currentSize] = e;
	trickleUp(currentSize++);
}

/*
判断什么时候需要将结点向上移动呢?
其实就是当index的父亲结点比index结点小时,将父亲结点的值赋给index结点,然后父亲结点变为index结点继续接下来的活动
可以类比有序数组中插入某个元素,最后一个元素上移相当于数组中后面的元素下移
就是将数组从最后一位元素开始,只要满足某个条件就下移,不满足时就停止,停止的地方就是插入的地方
*/
template <class T>
void MaxHeap<T>::trickleUp(int index)
{
	T bottom = heapArray[index];
	while (index > 0) {
		int parent = (index - 1) / 2;
		if (heapArray[parent] < bottom) {
			heapArray[index] = heapArray[parent];
			index = parent;
		}
		else {
			break;
		}
	}
	heapArray[index] = bottom;

}

template <class T>
const T& MaxHeap<T>::Top() const
{
	return heapArray[0];
}

template <class T>
void MaxHeap<T>::Pop()
{
	heapArray[0] = heapArray[--currentSize];
	trickleDown(0);
}

/*
同样类比上面:什么时候结点需要下移?
只有当该结点比最大的孩子小时,它不配做父亲,他就只能下移,
而一个结点下移相当于相应的结点上移,就是当index中两个孩子中较大的孩子比index要大时,则这个孩子的值赋值给index,然后这个孩子变为index
判断他的孩子是否会替代它

*/
template <class T>
void MaxHeap<T>::trickleDown(int index)
{
	int largerChild;
	T top = heapArray[index];
	//currentSize/2是因为叶子结点不再考虑
	while (index < currentSize / 2)
	{
		int leftChild = 2 * index + 1;
		int rightChild = leftChild + 1;
		if (rightChild < currentSize)/*右孩子存在才有的比*/ {
			if (heapArray[leftChild] < heapArray[rightChild]) {
				largerChild = rightChild;
			}
			else
				largerChild = leftChild;
		}
		else/*不存在还比啥,直接左孩子*/
			largerChild = leftChild;

		if (heapArray[largerChild]>top) {
			heapArray[index] = heapArray[largerChild];
			index = largerChild;
		}
		else {
			break;
		}
	}
	heapArray[index] = top;
}

#endif

main.cpp

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

using namespace std;

int main()
{

	MaxHeap<int> h(100);

	int arr[] = {62,3,90,27,33,8,12,9,43,66};

	for(int i=0; i<10; i++)
		h.Push(arr[i]);

	for(int i=0; i<10; i++)
	{
		arr[i] = h.Top();
		h.Pop();
	}

	for(int i=0; i<10; i++)
		cout << arr[i] << " ";
	cout << endl;

	cout << "OK" << endl;
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值