• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

Vigil

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

MOOC数据结构PTA05-树7 堆中的路径

题目

将一系列给定数字插入一个初始为空的小顶堆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 <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#define Maximum 1000
typedef struct hnode {
    /*堆数组*/
    int* data;
    /*当前个数*/
    int size;
    /*最大容量*/
    int capacity;
} Hnode, *Heap;

/*函数声明*/
Heap initHeap(int max);
bool isFull(Heap H);
bool isEmpty(Heap H);
bool insert(Heap H, int x);
int delete (Heap H);
void PercDown(Heap H, int p);
void buildMinHeap(Heap H);
void printPath(Heap H, int M);

/*主函数*/
int main() {
    int N, M;
    scanf("%d%d", &N, &M);
    int tempData;
    Heap H = initHeap(Maximum);
    for (int i = 1; i <= N; i++) {
        
        /*scanf("%d", &H->data[i]);
        H->size++;*/

        scanf("%d", &tempData);
        insert(H, tempData);
    }
    /*此种方式会导致叶节点顺序与输入顺序不同步*/
    //buildMinHeap(H);
    printPath(H, M);

    return 0;
}

/*函数定义*/
Heap initHeap(int max) {
    Heap H = (Heap)malloc(sizeof(Hnode));
    H->data = (int*)malloc((Maximum + 1) * sizeof(int));
    /*最小堆的哨兵*/
    H->data[0] = -10001;
    H->size = 0;
    H->capacity = Maximum;
    return H;
}
bool isFull(Heap H) {
    return (H->size == H->capacity);
}
bool isEmpty(Heap H) {
    return (H->size == 0);
}
bool insert(Heap H, int x) {
    if (isFull(H))
        return false;
    Heap temp;
    int seat = ++H->size;
    /*如果待插入位置的父亲大于待插入元素,将父亲下放*/
    while (x < H->data[seat / 2]) {
        H->data[seat] = H->data[seat / 2];
        seat = seat / 2;
    }
    H->data[seat] = x;
    return true;
}
int delete (Heap H) {
    if (isEmpty(H))
        return false;
    int seat, parent, child;
    int MaxItem = H->data[1];
    /* 用最大堆中最后一个元素从根结点开始向下过滤下层结点 */
    int x = H->data[H->size--]; /* 注意当前堆的规模要减小 */
    for (parent = 1; parent * 2 <= H->size; parent = child) {
        child = parent * 2;
        if (child != H->size) /* Child指向左右子结点的较小者 */
            child = (H->data[child] < H->data[child + 1]) ? child : child + 1;
        if (x <= H->data[child])
            break; /* 找到了合适位置 */
        else /* 向下滤X,把上层的根用child填充,即把小的child往上放 */
            H->data[parent] = H->data[child];
    }
    H->data[parent] = x;
    return MaxItem;
}
void PercDown(Heap H, int p) {
    /* 下滤:将H中以H->Data[p]为根的子堆调整为最xiao堆 */
    int Parent, Child;
    int X;

    X = H->data[p]; /* 取出根结点存放的值 */
    for (Parent = p; Parent * 2 <= H->size; Parent = Child) {
        Child = Parent * 2;
        if ((Child != H->size) && (H->data[Child] > H->data[Child + 1]))
            Child++; /* Child指向左右子结点的较xiao者 */
        if (X <= H->data[Child])
            break; /* 找到了合适位置 */
        else       /* 下滤X */
            H->data[Parent] = H->data[Child];
    }
    H->data[Parent] = X;
}
void buildMinHeap(Heap H) {
    /* 调整H->Data[]中的元素,使满足最大堆的有序性  */
    /* 这里假设所有H->Size个元素已经存在H->Data[]中 */

    int i;

    /* 从最后一个结点的父节点开始,到根结点1 */
    for (i = H->size / 2; i > 0; i--)
        PercDown(H, i);
}
void printPath(Heap H, int M) {
    int* index = (int*)malloc(M * sizeof(int));
    int temp;
    for (int i = 0; i < M; i++)
        scanf("%d", index + i);
    /*输出序列*/
    for (int i = 0; i < M; i++) {
        temp = index[i];
        while (temp > 1) {
            printf("%d ", H->data[temp]);
            temp /= 2;
        }
        if (i != M - 1)
            printf("%d\n", H->data[1]);
        else
            printf("%d", H->data[1]);
    }
}

image

posted on 2021-08-20 21:08  VigilYang  阅读(113)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3