将一系列给定数字插入一个初始为空的小顶堆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> ///堆常用于管理算法执行过程中的信息 堆排序和优先队列 using namespace std; const int maxn=1e5+20; int heap[maxn+1]; ///用heap数组表示堆 int n; ///先输入堆,再对其进行建造 int m; ///结点向下调整 high为想要调节的结点 void downAdjust(int low,int high) { int i=low; ///父亲节点 int j=i*2; while( j<= high) ///表示左孩子存在,但右孩子不一定存在 { if(j+1 <= high && heap[j+1]<heap[j]) ///表示右孩子存在 { j=j+1; } if(heap[i] > heap[j]) { swap(heap[j],heap[i]); i=j; j=i*2; }else{ break; } } } ///表示在heap[low,high]区间内进行排序 void UpAdjust(int low,int high) { int i=high; int j=i/2; while(j>=low) ///说明父亲节点如果存在的话 { if(heap[j] > heap[i]) { swap(heap[i],heap[j]); i=j; j=i/2; }else{ break; } } } void deleteHeap() { heap[1] = heap[n--]; ///将最大值删去并且将最后一个元素赋值给第一个元素然后在进行向下调整 downAdjust(1,n); } void CreatHeap() { for(int i=n/2; i>=1; i--) ///从n/2开始,倒着枚举 向下调整,意思是结点往下送 { downAdjust(i,n); } } ///插入操作,将新的元素值插入到堆的最后一个元素上,并做向上调整 void insertHeap(int x) { heap[++n] = x; UpAdjust(1,n); } void printHeap(int num) { for(int i=num; i>1; i=i/2) { cout<<heap[i]<<" "; } cout<<heap[1]<<endl; } int main() { int k; cin>>k; cin>>m; heap[0]=maxn; for(int i=1; i<=k; i++) { int x; cin>>x; insertHeap(x); } //CreatHeap(); for(int i=0; i<m; i++) { int num; cin>>num; printHeap(num); } return 0; }