题目来源:浙大陈越《数据结构》
将一系列给定数字插入一个初始为空的小顶堆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> /* Name: 给定堆桟元素的路径 Copyright: Author: demosses Date: 28/04/17 16:03 Description: 从给定的元素出发、找父节点、直到根节点 */ #define MinData -20000 typedef int ElementType; typedef struct HNode *Heap; struct HNode{ ElementType *Data; int Size; int Capacity; }; typedef Heap MinHeap; MinHeap Create( int MaxSize ) { /* 创建容量为MaxSize的空的最大堆 */ MinHeap H = malloc( sizeof( struct HNode ) ); H->Data = malloc( (MaxSize+1) * sizeof( ElementType ) ); H->Size = 0; H->Capacity = MaxSize; H->Data[0] = MinData; /* 定义"哨兵"为小于堆中所有可能元素的值*/ return H; } int IsFull(MinHeap H) { if(H->Size>H->Capacity ) return 1; else return 0; } void Insert( MinHeap H, ElementType item ) { /* 将元素item 插入最大堆H,其中H->Elements[0]已经定义为哨兵 */ int i; if ( IsFull(H) ) { printf("最大堆已满"); return; } i = ++H->Size; /* i指向插入后堆中的最后一个元素的位置 */ for ( ; H->Data[i/2] > item; i/=2 ) H->Data[i] = H->Data[i/2]; /* 向下过滤结点 */ H->Data[i] = item; /* 将item 插入 */ } void road(MinHeap H,int X) { int flag=1; for(;X>0;X=X/2) if (flag==1) printf("%d",H->Data[X],flag=0); else printf(" %d",H->Data[X]); } int main() { int N,L,X,LL; MinHeap A; scanf("%d",&N); scanf("%d",&L); A=Create(10001); for(;N>0;N--) { scanf("%d",&X); Insert(A,X); } for(;L>0;L--) { scanf("%d",&LL); road(A,LL); printf(" "); } return 0; }