05-树7 堆中的路径 (25 分)
将一系列给定数字插入一个初始为空的小顶堆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 <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
#define MaxSize 1000
//建堆,插入堆元素,打印路径三步
typedef struct HeapNode *MinHeap;
struct HeapNode{
int *Element; //堆由完全二叉树表示,可建立一个数组来存放元素
int size; //当前堆中元素个数
int capacity; //堆中可存放最大容量
};
MinHeap CreateHeap(int minSize)
{
MinHeap H;
H = (MinHeap)malloc(sizeof(struct HeapNode));
H->Element = (int *)malloc((MaxSize + 1) * sizeof(int));
H->capacity = MaxSize;
H->size = 0;
//0号设置为哨兵结点,保证输入的数据不会小于该数
H->Element[0] = minSize;
return H;
}
MinHeap InsertHeap(MinHeap H,int Data)
{
int i;
if(H->size==H->capacity) //最小堆已满,这题是多余的
return H;
i = ++H->size; //将插入的元素放入最后
H->Element[i] = Data;
for (; H->Element[i / 2] > Data;i/=2)//完全二叉树中,结点除以2就是其父亲结点,在i=1时必跳出循环
{
H->Element[i] = H->Element[i / 2]; //若父结点大于子结点则将父结点的值置于子结点
}
H->Element[i] = Data;
return H;
}
void PrintPath(MinHeap H,int Vertex)
{
int i;
for (i = Vertex; i != 1;i/=2) //同插入结点
{
printf("%d ", H->Element[i]);
}
printf("%d", H->Element[i]);
}
int main()
{
int N, M;
int first, second;
MinHeap H;
scanf("%d %d", &N, &M);
H = CreateHeap(-10001);
for (int i = 0; i < N;i++)
{
scanf("%d", &first);
H = InsertHeap(H, first);
}
for (int i = 0; i < M;i++)
{
scanf("%d", &second);
PrintPath(H, second);
printf("\n");
}
system("pause");
return 0;
}