7-5 堆中的路径

将一系列给定数字依次插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。

输入格式:

每组测试第1行包含2个正整数N和M(1000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。最后一行给出M个下标。

输出格式:

对输入中给出的每个下标i,在一行中输出从H[i]到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。

输入样例:

1
2
3
5 3
46 23 26 24 10
5 4 3

输出样例:

1
2
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一次。

 

向堆中插入

代码:

1
2
3
4
5
for(int i=1;i<=n;i++){
        scanf("%d",&x);
        H[i]=x;
        up(1,i);
    }

 

downAdjust

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void down(int low,int high){
    int i=low,j=i*2;
    while(j<=high){
        <strong>if(j+1<=high && H[j+1]<H[j]){
            j=j+1;
        }</strong>
        if(H[j]<H[i]){
            int t=H[j];
            H[j]=H[i];
            H[i]=t;
            i=j;
            j=i*2;
        }
        else{
           <strong> break;</strong>
        }
    }
}

 

 

upAdjust

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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{
            <strong>break;</strong>
        }
    }
}

 

posted @   Yohoc  阅读(71)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示