用二叉树实现大顶堆

一、大顶堆与小顶堆的数据结构

   

     即:大顶堆的每个分支上元素越来越小

            小顶堆的每个分支上元素越来越大

二、大顶堆可以用数组实现,也可以用链表实现,本篇用数组来实现大顶堆

一个规律, 从上图中可以看出: patent_index = (child_index -1 ) /2;   //取整

三、大顶堆的两个操作:插入新节点和删除根节点

 

四、代码实现和运行结果


#include <iostream>

using namespace std;

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

	~MaxHeap();

	bool isEmpty();

	void push(const T &val);

	T& top();

	void pop();


private:
	T *heapArry;  //大顶堆的内存指针
	int maxSize;  //大顶堆的最大元素个数
	int currSize; //大顶堆当前元素个数

	void trickleUp(int index); //向上渗透
	void trickleDown(int index); //向下渗透

};


template <class T>
MaxHeap<T>::MaxHeap(int mx)
{
	maxSize = mx;
	currSize = 0;

	heapArry = new T[mx];

}

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

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

template <class T>
void MaxHeap<T>::push(const T &val)
{
	if (currSize >= maxSize)
	{
		cout << "stack is full" << endl;

		return;
	}

	heapArry[currSize] = val;
	trickleUp(currSize);
	currSize++;
}

template <class T>
void MaxHeap<T>::trickleUp(int index)
{
	int parent = (index - 1) / 2;  //得到parent的index

	T bottom = heapArry[index];

	while (index > 0 && bottom > heapArry[parent])  //向上渗透的条件
	{
		heapArry[index] = heapArry[parent];  //这里是parent来下边了
		index = parent;
		parent = (parent - 1) / 2;

	}

	heapArry[index] = bottom;
}

template <class T>
T & MaxHeap<T>::top()
{
	return heapArry[0];
}

template <class T>
void MaxHeap<T>::pop()
{
	heapArry[0] = heapArry[--currSize];  //把最后一个拿到栈顶来
	trickleDown(0);  //然后向下渗透
}


template <class T>
void MaxHeap<T>::trickleDown(int index)
{
	int largerChild; //较大一个孩子的index
	T top = heapArry[index]; //暂存栈顶元素

	while (index < currSize / 2) //最大循环到 currSize/2位置处
	{
		int leftChild = 2 * index + 1;  //左孩子的位置
		int rightChild = leftChild + 1; //右孩子等于左孩子+1

		if ((rightChild < currSize) && (heapArry[leftChild] < heapArry[rightChild]))
			largerChild = rightChild;
		else
			largerChild = leftChild;

		if (top >= heapArry[largerChild]) //如果栈顶元素大于heap中的较大的元素,那么就找到了合适的位置
			break;

		heapArry[index] = heapArry[largerChild]; //否则的话继续向下渗透
		index = largerChild;

	}
	heapArry[index] = top; //位置在子节点的父亲节点上,而不是在子节点上
}

void max_heap_general_test(void)
{
	MaxHeap<int> hp(100);

	hp.push(10);
	cout << "top:" << hp.top() << endl;
	hp.push(20);
	hp.push(30);
	cout << "top:" << hp.top() << endl;
	hp.push(50);
	cout << "top:" << hp.top() << endl;
	hp.push(5);
	cout << "top:" << hp.top() << endl;

	hp.pop();
	cout << "pop 1,top:" << hp.top() << endl;
	hp.pop();
	cout << "pop 2,top:" << hp.top() << endl;
	hp.pop();
	cout << "pop 3,top:" << hp.top() << endl;
	hp.pop();
	cout << "pop 4,top:" << hp.top() << endl;
}
//利用大顶堆排序
void max_heap_sort(void)
{
	int arr[10] = {5,3,10,1,9,2,8,6,4,7};
	int lop = 0;

	MaxHeap<int> hp(100);

	for (lop = 0; lop < 10; lop++)
		hp.push(arr[lop]);

	for (lop = 0; lop < 10; lop++)
	{
		arr[lop] = hp.top(); //每次取大顶堆的根元素

		hp.pop();   //取完后删除
	}
		
	for (lop = 0; lop < 10; lop++)
		cout << arr[lop] << endl;

}

int main()
{
	//max_heap_general_test();
	max_heap_sort();

	return 0;
}


 max_heap_general_test():

利用大顶堆进行排序:

max_heap_sort()

猜你喜欢

转载自blog.csdn.net/weixin_40204595/article/details/108582516