一、大顶堆与小顶堆的数据结构
即:大顶堆的每个分支上元素越来越小
小顶堆的每个分支上元素越来越大
二、大顶堆可以用数组实现,也可以用链表实现,本篇用数组来实现大顶堆
一个规律, 从上图中可以看出: 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()