题目:https://pintia.cn/problem-sets/434/problems/6104
说明:代码中特意写了DeleteMin(MinHeap)最小堆的删除的函数
AC代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#define MINDATA -1e5-5
using namespace std;
typedef int ElementType;
typedef struct HNode* Heap;
struct HNode{
ElementType * Data;/*存储元素的数组*/
int Size; /*堆中当前元素个数*/
int Capacity; /*堆的最大容量*/
};
typedef Heap MinHeap; /*最小堆*/
MinHeap CreateHeap(ElementType MaxSize)
{/*创建容量为MaxSize的空的最小堆*/
MinHeap H=(MinHeap) malloc (sizeof(struct HNode) );
H->Data = (ElementType*) malloc( (MaxSize+1) * sizeof(ElementType) );
H->Size =0;
H->Capacity = MaxSize ;
H->Data[0] = MINDATA ; /*定义“哨兵”为大于堆中所有可能元素的值*/
return H;
}
bool Insert ( MinHeap H, ElementType X )
{/*将元素X插入最小堆H,其中H->DAta[0]已经定义为哨兵*/
int i;
if( H->Size == H->Capacity ){
printf("MinHeap is Full!");
return false;
}
i=++H->Size;/*i指向插入后堆中的最后一个元素的位置*/
for( ; H->Data[i/2] > X ; i/=2)
H->Data[i]=H->Data[i/2]; /*上滤X*/
H->Data[i]=X; /*将X插入*/
return true;
}
#define ERROR -1e9/*错误标识应定义为堆中不可能出现的元素值*/
ElementType DeleteMin( MinHeap H)
{/*从最小堆H中取出键值最小的元素,并删除一个结点*/
int Parent , Child;
ElementType MinItem, X;
if(H->Size==0) {
cout<<"最小堆已空"<<endl;
return ERROR;
}
MinItem = H->Data[1];/*取出根结点存放的最小值*/
/*用最小堆中最后一个元素从根结点开始从上过滤下层结点*/
X=H->Data[H->Size--]; /*当前堆的规模要减小*/
for(Parent=1; Parent*2<=H->Size; Parent = Child){
Child = Parent *2;
if( (Child!=H->Size) && (H->Data[Child] > H->Data[Child+1]) )
Child++; /*Child 指向左右子结点中较小者*/
if(X<= H->Data[Child]) break;
else /*下滤X */
H->Data[Parent]= H->Data[Child];
}
H->Data[Parent] = X;
return MinItem;
}
int main(){
MinHeap H = CreateHeap(1001);
int N,M,X,i,j;
cin>>N>>M;
for(i=0;i<N;i++){
cin>>X;
Insert(H,X);
}
for(i=0;i<M;i++){
cin>>j;
bool flag=false;
while(j>=1){
if(!flag){
cout<<H->Data[j];
flag=true;
}
else cout<<' '<<H->Data[j];
j/=2;
}
cout<<endl;
}
}