7-5 堆中的路径
作者:互联网
将一系列给定数字依次插入一个初始为空的小顶堆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>
#include <iostream>
#include <set>
typedef struct Node* Tree;
struct Node{
int data;
Tree left;
Tree right;
};
int H[1005];
//void down(int low,int high){
// int i=low,j=i*2;
// while(j<=high){
// if(j+1<=high && H[j+1]<H[j]){
// j=j+1;
// }
// if(H[j]<H[i]){
// int t=H[j];
// H[j]=H[i];
// H[i]=t;
// i=j;
// j=i*2;
// }
// else{
// break;
// }
// }
//
}
void up(int low,int high){
int i=high,j=i/2;
while(j>=low){
if(H[j]>H[i]){
int tmp=H[j];
H[j]=H[i];
H[i]=tmp;
i=j;
j=i/2;
}else{
break;
}
}
}
using namespace std;
int main()
{
int n,m,x;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&x);
H[i]=x;
up(1,i);
}
for(int i=0;i<m;i++){
int index;
bool flag=false;
scanf("%d",&index);
while(index>=1){
if(flag==true){
printf(" ");
}
flag=true;
printf("%d",H[index]);
index=index/2;
}
printf("\n");
}
return 0;
}
知识点:
堆本质上是一个完全二叉树,同时又具有属性(每个节点的值不小于/大于存储在其每个子节点中的值。)( Heap Order property. )
卡点:
要注意,题目中说的是 往一个空的堆内依次,我开始理解并写成了将所有数读入数组后,在最后downAdjust来调整以满足堆的性质。但实际上需要每向数组中读入一个数后就要upAdjust一次。
向堆中插入
代码:
for(int i=1;i<=n;i++){ scanf("%d",&x); H[i]=x; up(1,i); }
downAdjust
void down(int low,int high){ int i=low,j=i*2; while(j<=high){ if(j+1<=high && H[j+1]<H[j]){ j=j+1; } if(H[j]<H[i]){ int t=H[j]; H[j]=H[i]; H[i]=t; i=j; j=i*2; } else{ break; } } }
upAdjust
void up(int low,int high){ int i=high,j=i/2; while(j>=low){ if(H[j]>H[i]){ int tmp=H[j]; H[j]=H[i]; H[i]=tmp; i=j; j=i/2; }else{ break; } } }
标签:index,int,void,路径,high,while,low,堆中 来源: https://www.cnblogs.com/yccy/p/16518519.html