//大根堆的构建、结点的插入和删除与此完全类似
#include<iostream>
using namespace std;
class MinHeap
{
public:
int* heap;//存放小根堆中元素的数组
int maxHeapSize;//小根堆最多允许元素个数
int currentSize;//小根堆中当前元素个数
public:
MinHeap(int sz){
maxHeapSize=sz;
heap=new int[maxHeapSize];
currentSize=0;
}
MinHeap(int arr[],int n,int sz){ //数组传参后,传的是指针,sizeof(arr)不能计算出该数组有多少个字节,而是该指针变量所占字节,
maxHeapSize=sz; //在这里sizeof(arr)=4
heap=new int[maxHeapSize];
for(int i=0;i<n;i++){
heap[i]=arr[i];
}
currentSize=n;
int currentPos=(currentSize-1-1)/2;//堆(完全二叉树)的最后一个节点的父节点
while(currentPos>=0){
siftDown(currentPos,currentSize-1);
currentPos--;
}
}
void siftDown(int start,int m) //m接收的实参是堆(完全二叉树)的最后一个节点
{
int i=start,j=2*i+1; //i指父结点,j指左孩子结点
int temp=heap[i];
while(j<=m)
{
if(j<m&&heap[j]>heap[j+1])
{
j++;
}
if(temp<=heap[j])
{
break;
}
else
{
heap[i]=heap[j];
i=j;
j=2*j+1;
}
}
heap[i]=temp;
}
void siftUp(int start)
{
int j=start,i=(j-1)/2; //j可为左孩子也可右孩子,i指父结点
int temp=heap[j];
while(j>0)
{
if(heap[i]<=temp)
{
break;
}
else
{
heap[j]=heap[i];
j=i;
i=(i-1)/2;
}
}
heap[j]=temp;
}
bool Insert(int x)
{
if(currentSize==maxHeapSize)
{
return false;
}
heap[currentSize]=x;
siftUp(currentSize);
currentSize++;
return true;
}
int RemoveMin()
{
if(!currentSize)
{
return false;
}
int x=heap[0];
heap[0]=heap[currentSize-1];
currentSize--;
siftDown(0,currentSize-1);
return x;
}
void show(){
for(int i=0;i<currentSize;i++){
cout<<heap[i]<<" ";
}
}
};
int main()
{
int arr[]={53,17,78,9,45,65,87,23};
int n=sizeof(arr)/sizeof(int);
MinHeap minHeap(arr,n,50);
minHeap.show();
cout<<endl;
minHeap.Insert(1);//插入1
minHeap.show();
cout<<endl;
cout<<"删除的堆顶元素:"<<minHeap.RemoveMin()<<endl;//删除堆顶元素,并返回原堆顶元素
minHeap.show();
cout<<endl;
return 0;
}
//9 17 65 23 45 78 87 53
//1 9 65 17 45 78 87 53 23
//删除的堆顶元素:1
//9 17 65 23 45 78 87 53