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 <stdio.h>
#include <stdlib.h>

#define MAXSIZE 1000    //小顶堆的容量
#define MINVALUE -10001 //小顶堆的哨兵值,放在下标为0的位置

struct HeapStruct {
    int *data;          //用数组来表示完全二叉树
    int size;           //当前堆中的结点数
};
typedef struct HeapStruct *MinHeap;

MinHeap createHeap();   //创建堆
void insertHeap(MinHeap heap, int data);    //向堆中插入元素

int main() {
    int N, M;
    scanf("%d %d", &N, &M);
    MinHeap heap = createHeap();
    for (int i = 0; i < N; i++) {
        int data;
        scanf("%d", &data);
        insertHeap(heap, data); //读取N个值,将它们依次插入堆中
    }
    for (int i = 0; i < M; i++) {
        int index;
        scanf("%d", &index);
        for ( ; index >= 1; index /= 2) {   //通过下标除以2来找到父结点,直到下标为1
            if (index == 1) printf("%d\n", heap->data[index]);  
            else printf("%d ", heap->data[index]);
        }
    }
}

MinHeap createHeap() {
    MinHeap minHeap = (MinHeap) malloc(sizeof(struct HeapStruct));  //为堆分配空间
    minHeap->data = (int *) malloc((MAXSIZE + 1) * sizeof(int));    //为数组分配空间,注意大小为最大容量+1,因为0放的哨兵值
    minHeap->size = 0;
    minHeap->data[0] = MINVALUE;    //下标0放哨兵值
    return minHeap;
}

void insertHeap(MinHeap heap, int data) {
    if (heap->size == MAXSIZE) return;
    heap->data[++heap->size] = data;
    int i = heap->size;
    for ( ; heap->data[i / 2] > data; i /= 2) { 
        heap->data[i] = heap->data[i / 2];  //将插入值与父结点比较,若父结点大则下浮
    }
    heap->data[i] = data;
}
posted @ 2020-03-24 17:22  AndyHY  阅读(174)  评论(0编辑  收藏  举报