1155 Heap Paths (30 分)

跟着柳婼学姐学习的笔记ヾ(≧▽≦*)o


原题目: 1155 Heap Paths (30 分).

题意

给出一棵完全二叉树的层序遍历序列(无重复数值),
① 打印出所有叶子节点到根节点的路径,并且按从右到左的顺序;
② 最后,判断是否是heap,是max(父结点不小于孩子)还是min(父结点不大于孩子)。

分析

  1. 将题给序列存在数组中,则可以通过下标访问结点及其孩子结点、父结点。
  2. 打印路径:① 用DFS递归实现先序(根右左)遍历;② 需要额外的数组 存储push_back()维护pop_back() 路径。
  3. 判断heap:从数组的2号元素开始,依次与其父结点 i/2 比较大小。

知识点

  1. 用数组存储完全二叉树——下标亲戚关系、层序遍历序列、叶结点与空结点判断(常作递归边界)。👉 传送门:堆(Heap):完全二叉树(Complete Binary Tree)⭐⭐⭐【常忘用】
  2. DFS之先序遍历——递归必备:递归边界+递归式。
  3. vector的应用——用push_back()与pop_back()实现路径维护(类似栈,但是vector数组可以随机访问)。

词汇

WORDS & CHUNKS释义WORDS & CHUNKS释义
path路径implementation实现,实施
the level order traversal sequence层序遍历序列property性质
in non-increasing/non-decreasing order非递增/非递减DFS(Depth-First-Search)深度优先搜索

CODE

#include <iostream>
#include <vector>
using namespace std;
int n;
vector<int> v, pre;  //层序遍历序列(从1号开始),先序遍历路径(从0号开始)
void DFS(int index);  //输出路径
int main()
{
    cin >> n;
    v.resize(n+1);
    for ( int i=1; i<=n; i++ )
        cin >> v[i];   //完全二叉树的层序遍历序列与数组顺序相同
    //DFS递归遍历
    DFS(1);
    //判断heap
    int isMin = 1, isMax = 1;  //1代表”是Min/Max heap
    for (int i=2; i<=n; i++ ){  //每个结点i与其父结点i/2比较
        if ( v[i]>v[i/2] ) isMax = 0;
        else if ( v[i]<v[i/2] ) isMin = 0;
        if ( !isMin && !isMax ) break;  //Not Heap时提前结束循环
    }
    if ( isMin || isMax ){
        printf("%s Heap", isMin==1 ? "Min" : "Max" );
    }
    else
        cout << "Not Heap";
    
    return 0;
}
void DFS(int index){   //用数组下标来直接访问
    if ( index>n ) return;
    if ( index*2>n && index<=n ){   //递归边界:叶子结点 → 输出路径
        pre.push_back(v[index]);   //叶子结点也需压入
        for ( int i=0; i<pre.size(); i++ )
            printf("%d%s",pre[i], i==pre.size()-1 ? "\n" : " ");
        return;
    }
    //访问根结点
    pre.push_back(v[index]);
    //优先遍历右子树
    if ( index*2+1<=n ){  //若有右孩子
        DFS(index*2+1);
        pre.pop_back();
    }
    DFS(index*2);
    pre.pop_back();
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值