将一系列给定数字插入一个初始为空的小顶堆H[]
。随后对任意给定的下标i
,打印从H[i]
到根结点的路径。
输入格式:
每组测试第1行包含2个正整数N和M(≤1000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。最后一行给出M个下标。
输出格式:
对输入中给出的每个下标i
,在一行中输出从H[i]
到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。
输入样例:
5 3
46 23 26 24 10
5 4 3
输出样例:
24 23 10
46 23 10
26 10
答案如下
#include <stdio.h>
#include<stdlib.h>
typedef struct HNode *Heap; /* 堆的类型定义 */
struct HNode {
int *Data; /* 存储元素的数组 */
int Size; /* 堆中当前元素个数 */
int Capacity; /* 堆的最大容量 */
};
typedef Heap MaxHeap; /* 最大堆 */
typedef Heap MinHeap; /* 最小堆 */
#define MINDATA -100001 /* 该值应根据具体情况定义为大于堆中所有可能元素的值 */
MinHeap CreateHeap( int MaxSize )
{ /* 创建容量为MaxSize的空的最大堆 */
MinHeap H = (MinHeap)malloc(sizeof(struct HNode));
H->Data = (int *)malloc((MaxSize+1)*sizeof(int));
H->Size = 0;
H->Capacity = MaxSize;
H->Data[0] = MINDATA; /* 定义"哨兵"为大于堆中所有可能元素的值*/
return H;
}
bool IsFull( MinHeap H )
{
return (H->Size == H->Capacity);
}
bool Insert( MinHeap H, int X )
{ /* 将元素X插入最小堆H,其中H->Data[0]已经定义为哨兵 */
int i;
if ( IsFull(H) ) {
printf("最小堆已满");
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;
}
void PathTraverse(Heap h,int indix){
if (indix<=h->Size&&indix>0){
printf("%d",h->Data[indix]);
indix/=2;
for (;indix>0;indix/=2)
printf(" %d",h->Data[indix]);
}
else
printf("请输入正确的下标");
}
int main(){
int N,M;
scanf("%d %d",&N,&M);
Heap H=CreateHeap(N+1);
int i=1,data;
for (;i<=N;i++){
H->Size=i-1;
scanf("%d",&data);
Insert(H,data);
}
int indix;
for (i=0;i<M;i++)
{
scanf("%d",&indix);
PathTraverse(H,indix);
printf("\n");
}
return 0;
}