一,实现
#include<iostream>
#include<vector>
using namespace std;
template<class T>
class maxHeap{
private:
int size;
int capacity;
T* heap;
public:
maxHeap(int _capacity){
size=0;
capacity=_capacity;
heap=new T[capacity];
}
~maxHeap(){
delete[] heap;
}
bool empty(){
if(size==0){
return true;
}
return false;
}
void insert(T value){
if(size<capacity){
heap[size++]=value;
int index=size;
while(index>1){
//调堆
if(heap[index]>heap[index/2]){
swap(heap[index],heap[index/2]);
}
index/=2;
}
}
else return;
}
void delete_max(){
if(size==0)return ;
//用最后一个结点将第一个结点替换,替换结束后最后一个结点为原本第一个结点,size--表示删除最后一个结点
swap(heap[1],heap[size--]);
int index=1;
while(index<=size){
//调堆
int p=2*index;
if(p<size&&heap[p]<heap[p+1]){
//找孩子节点中最大的一个
p++;
}
swap(heap[p],heap[index]);
index=p;
}
}
T max_value(){
if(empty())return -1;
else return heap[1];
}
};
void BuildHeap(int res[], int size) //用数组创建堆
{
for (int i = size / 2; i >= 1; --i)
{
int temp = res[i];
int index = 2 * i;
while (index <= size)
{
if (index < size &&res[index] < res[index + 1])
index++;
if (res[index] > temp)
{
res[index / 2] = res[index];
index *= 2;
}
else
break;
}
res[index / 2] = temp;
}
}
template<class T>
void TestMaxHeap()
{
int res[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
BuildHeap(res, 9);
for (int i = 1; i < 10; ++i)
{
cout << res[i] << " ";
}
}
二,复杂度讨论
插入时间复杂度
将元素插入最后一位,再进行向上冒泡,即如果父节点的值小于被插入的元素,父节点下移,被插入的元素上移。时间复杂度取决于树的高度h。而完全二叉树的树的高度为[logn+1]的上取整,所示时间复杂度为O(logn)。
删除时间复杂度
删除操作的逻辑为,删除堆的根节点,将最后一个节点补到根节点位置,得到一颗不符合规则的堆。再对根节点进行向下冒泡,即如果父节点小于某一孩子或所有孩子,将元素值最大 的孩子与父节点交换。孩子上移,父节点下移,下移后与孩子重复该操作,直到比孩子都大或没有孩子。
删除操作向下冒泡,操作时间还是取决于树的高度,时间复杂度为O(logn)