AcWing 1640:堆 ← 判断堆类型?

【题目来源】
https://www.acwing.com/problem/content/1642/

【题目描述】
在计算机科学中,堆是一种的基于树的专用数据结构,它具有堆属性:
如果 P 是 C 的父结点,则在大顶堆中 P 结点的权值大于或等于 C 结点的权值,在小顶堆中 P 结点的权值小于或等于 C 结点的权值。
一种堆的常见实现是二叉堆,它是由完全二叉树来实现的。
你的任务是判断给定的完全二叉树是否是堆。

【输入格式】
第一行包含两个整数 M 和 N,分别表示给定完全二叉树的数量以及每个完全二叉树包含的结点数量。
接下来 M 行,每行包含 N 个不同的整数(都在 int 范围内),表示一个完全二叉树的层序遍历序列。

【输出格式】
对于每个给定的二叉树,首先输出一行对它是否是堆的判断结论。
如果是大顶堆,则输出 Max Heap,如果是小顶堆,则输出 Min Heap,如果不是堆,则输出 Not Heap。
然后,再输出一行它的后序遍历序列。
同行数字用空格隔开,行首行尾不得有多余空格。

【输入样例】
3 8
98 72 86 60 65 12 23 50
8 38 25 58 52 82 70 60
10 28 15 12 34 9 8 56

【输出样例】
Max Heap
50 60 65 72 12 23 86 98
Min Heap
60 58 52 38 82 70 25 8
Not Heap
56 12 34 28 9 8 15 10​​​​​​​

【数据范围】
1≤M≤100,
1<N≤1000

【算法分析】
● 代码中的 dfs 函数,实现了二叉树的后序遍历。
● 通常,二叉树的输入顺序是“按层从左到右‌依次输入”‌,二叉树的层序遍历规则是“按层从左到右访问”,因此两者顺序相同。​​​​​​​

【算法代码】

#include <bits/stdc++.h>
using namespace std;

const int maxn=1e3+5;
int a[maxn];
int m,n;

void dfs(int u) {
    if(u>n) return;
    dfs(u*2);
    dfs(u*2+1);
    cout<<a[u]<<" ";
}

int main() {
    cin>>m>>n;
    while(m--) {
        for(int i=1; i<=n; i++) cin>>a[i];

        int bih=0; //big heap
        int smh=0; //small heap
        for(int i=1; i<=n; i++) {
            for(int j=0; j<2; j++) {
                if(i*2+j>n) continue;
                if(a[i]>=a[i*2+j]) bih=1;
                if(a[i]<=a[i*2+j]) smh=1;
            }
        }

        if(smh && bih) cout<<"Not Heap\n";
        else if(bih) cout<<"Max Heap\n";
        else cout<<"Min Heap\n";

        dfs(1);
        cout<<endl;
    }

    return 0;
}

/*
in:
3 8
98 72 86 60 65 12 23 50
8 38 25 58 52 82 70 60
10 28 15 12 34 9 8 56

out:
Max Heap
50 60 65 72 12 23 86 98
Min Heap
60 58 52 38 82 70 25 8
Not Heap
56 12 34 28 9 8 15 10
*/





【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/146358448
https://blog.csdn.net/hnjzsyjyj/article/details/146352473
https://www.acwing.com/solution/content/153656/


 

posted @ 2025-11-14 08:15  Triwa  阅读(7)  评论(0)    收藏  举报