news 2026/10/10 6:16:37

[GESP202603 六级] 完全二叉树

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[GESP202603 六级] 完全二叉树

视频讲解:[GESP202603 六级] 完全二叉树-信息学奥赛GESP等级考试真题解析

一、原题

题目描述

给定一棵包含 n 个结点的有根二叉树,结点依次以 1,2,…,n 编号,根结点编号为 1。

对于结点 i,其左儿子的编号记为 li​,右儿子编号记为 ri​。特别地,如果左儿子不存在则 li​=0,如果右儿子不存在则 ri​=0。

树中每个结点都对应一棵以其为根的子树。请你求出给定有根树的所有 n 棵子树中,有多少棵子树是完全二叉树。

输入格式

第一行,一个正整数 n,表示有根二叉树结点数量。

接下来 n 行,每行两个正整数 li​,ri​,表示结点 i 的左儿子编号和右儿子编号。

输出格式

输出一行,一个整数,表示所有子树中完全二叉树的数量。

输入输出样例

输入 #1

4 2 3 4 0 0 0 0 0

输出 #1

4

输入 #2

4 2 3 0 0 4 0 0 0

输出 #2

3

说明/提示

对于 40% 的测试点,保证 1≤n≤500。

对于所有测试点,保证 1≤n≤10^5。

二、做题思路

1)二维数组构造二叉树

#include<bits/stdc++.h> using namespace std; int tree[100005][2]; int main(){ //1)二维数组构造二叉树 //1.1)确定结点数量n int n;cin>>n; //1.2)填充每个结点左右子树 for(int i=1;i<=n;i++) cin>>tree[i][0]>>tree[i][1]; }

2)深搜每一个结点

#include<bits/stdc++.h> using namespace std; int tree[100005][2]; void dfs(int x){ //2.2)子树不为空,就向下搜索 if(tree[x][0]!=0) dfs(tree[x][0]); if(tree[x][1]!=0) dfs(tree[x][1]); } int main(){ //1)二维数组构造二叉树 //... //2)深搜每一个结点 //2.1)深搜函数,从1开始 dfs(1); }

3)判断是否为完全二叉

3.1)叶子节点,是完全二叉,是满二叉,高度为1

#include<bits/stdc++.h> using namespace std; int tree[100005][2]; int d[100005]; bool m[100005],w[100005]; void dfs(int x){ //3)判断是否为完全二叉树 //3.1)叶子节点,是完全二叉,是满二叉,高度为1 if(!tree[x][0]&&!tree[x][1]){//左右为空是叶子节点 w[x]=m[x]=d[x]=1; return ; } //2.2)子树不为空,就向下搜索 //... } int main(){ //1)二维数组构造二叉树 //... //2)深搜每一个结点 //2.1)深搜函数,从1开始 dfs(1); }
3.2)计算高度

#include<bits/stdc++.h> using namespace std; int tree[100005][2]; int d[100005]; bool m[100005],w[100005]; void dfs(int x){ //3)判断是否为完全二叉树 //3.1)叶子节点,是完全二叉,是满二叉,高度为1 //... //2.2)子树不为空,就向下搜索 //... //3.2)计算高度 (左右取大的+1) d[x]=max(d[tree[x][0]],d[tree[x][1]])+1; } int main(){ //1)二维数组构造二叉树 //... //2)深搜每一个结点 //2.1)深搜函数,从1开始 dfs(1); }
3.3)判断满二叉

#include<bits/stdc++.h> using namespace std; int tree[100005][2]; int d[100005]; bool m[100005],w[100005]; void dfs(int x){ //3)判断是否为完全二叉树 //3.1)叶子节点,是完全二叉,是满二叉,高度为1 //... //2.2)子树不为空,就向下搜索 //... //3.2)计算高度 (左右取大的+1) //... //3.3)判断满二叉:左右高度相同,左右都是满二叉 if(d[tree[x][0]]==d[tree[x][1]]&&m[tree[x][0]]&&m[tree[x][1]]) m[x]=1; } int main(){ //1)二维数组构造二叉树 //... //2)深搜每一个结点 //2.1)深搜函数,从1开始 dfs(1); }
3.4)判断完全二叉的2种情况

#include<bits/stdc++.h> using namespace std; int tree[100005][2]; int d[100005]; bool m[100005],w[100005]; void dfs(int x){ //3)判断是否为完全二叉树 //3.1)叶子节点,是完全二叉,是满二叉,高度为1 //... //2.2)子树不为空,就向下搜索 //... //3.2)计算高度 (左右取大的+1) //... //3.3)判断满二叉:左右高度相同,左右都是满二叉 //... //3.4)判断完全二叉的2种情况 //左右高度相同:左满 且 右完全 if(d[tree[x][0]]==d[tree[x][1]]) if(m[tree[x][0]]&&w[tree[x][1]]) w[x]=1; //左高度==右高度+1:左完全 且 右满或空 if(d[tree[x][0]]==d[tree[x][1]]+1) if(w[tree[x][0]]&&(m[tree[x][1]]||!tree[x][1])) w[x]=1; } int main(){ //1)二维数组构造二叉树 //... //2)深搜每一个结点 //2.1)深搜函数,从1开始 dfs(1); }

4)计算完全二叉数量

#include<bits/stdc++.h> using namespace std; int tree[100005][2]; int d[100005]; bool m[100005],w[100005]; void dfs(int x){ //3)判断是否为完全二叉树 //3.1)叶子节点,是完全二叉,是满二叉,高度为1 //... //2.2)子树不为空,就向下搜索 //... //3.2)计算高度 (左右取大的+1) //... //3.3)判断满二叉:左右高度相同,左右都是满二叉 //... //3.4)判断完全二叉的2种情况 //左右高度相同:左满 且 右完全 //.. } int main(){ //1)二维数组构造二叉树 //... //2)深搜每一个结点 //2.1)深搜函数,从1开始 dfs(1); //4)计算完全二叉数量 int ans=0; for(int i=1;i<=n;i++) if(w[i]) ans++; cout<<ans; }

三、答案

#include<bits/stdc++.h> using namespace std; int tree[100005][2]; int d[100005]; bool m[100005],w[100005]; void dfs(int x){ //3)判断是否为完全二叉树 //3.1)叶子节点,是完全二叉,是满二叉,高度为1 if(!tree[x][0]&&!tree[x][1]){//左右为空是叶子节点 w[x]=m[x]=d[x]=1; return ; } //2.2)子树不为空,就向下搜索 if(tree[x][0]!=0) dfs(tree[x][0]); if(tree[x][1]!=0) dfs(tree[x][1]); //3.2)计算高度 d[x]=max(d[tree[x][0]],d[tree[x][1]])+1; //3.3)判断满二叉:左右高度相同,左右都是满二叉 if(d[tree[x][0]]==d[tree[x][1]]&&m[tree[x][0]]&&m[tree[x][1]]) m[x]=1; //3.4)判断完全二叉的2种情况 //左右高度相同:左满 且 右完全 if(d[tree[x][0]]==d[tree[x][1]]) if(m[tree[x][0]]&&w[tree[x][1]]) w[x]=1; //左高度==右高度+1:左完全 且 右满或空 if(d[tree[x][0]]==d[tree[x][1]]+1) if(w[tree[x][0]]&&(m[tree[x][1]]||!tree[x][1])) w[x]=1; } int main(){ //1)二维数组构造二叉树 //1.1)确定结点数量n int n;cin>>n; //1.2)填充每个结点左右子树 for(int i=1;i<=n;i++) cin>>tree[i][0]>>tree[i][1]; //2)深搜每一个结点 //2.1)深搜函数,从1开始 dfs(1); //4)计算完全二叉数量 int ans=0; for(int i=1;i<=n;i++) if(w[i]) ans++; cout<<ans; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 6:16:37

2026 版高中英语试题调研热点题型专项阅读理解备考资料

这套资料专门针对高考英语阅读理解板块打造&#xff0c;包含阅读原题训练与配套深度解析&#xff0c;覆盖常规阅读题型以及7选5题型&#xff0c;针对性突破阅读难点&#xff0c;掌握解题思路&#xff0c;提升阅读答题正确率。 &#x1f4e5;资料获取方式 【2026版高中《试题调…

作者头像 李华
网站建设 2026/10/10 6:15:46

page_alloc fallbacks[][]

伙伴系统中迁移类型降级&#xff08;fallback&#xff09;的优先级表。当某种迁移类型的空闲链表耗尽时&#xff0c;分配器按这个表尝试从其他类型"偷"页。一、背景&#xff1a;为什么需要 fallback&#xff1f;迁移类型与反碎片空闲页按迁移类型分组&#xff08;MIG…

作者头像 李华
网站建设 2026/10/10 6:14:37

从目的到落地:motion-design-skill四级决策框架完整教程

从目的到落地&#xff1a;motion-design-skill四级决策框架完整教程 【免费下载链接】motion-design-skill Universal motion design principles for AI agents — timing, easing, choreography, and Disney animation principles adapted for UI 项目地址: https://gitcode…

作者头像 李华
网站建设 2026/10/10 6:11:35

从OpenGL到现代图形API:渲染思维与架构迁移实战

1. 为什么“会写OpenGL”不等于“懂现代渲染”很多做了五六年OpenGL的朋友&#xff0c;第一次接触现代图形API时都会有一种强烈的挫败感&#xff1a;明明以前几十行就能画出一个三角形&#xff0c;现在光是初始化就要写几百行&#xff1b;以前改一个状态直接调函数就行&#xf…

作者头像 李华
网站建设 2026/10/10 6:11:33

同样是 AI 成片,知漫剧为什么能做到角色画风不跑偏?

绝大多数 AI 漫剧创作者都会遇到同一个棘手难题&#xff1a;批量制作连载剧集时&#xff0c;人物五官、造型、画面画风不断变化&#xff0c;单集单独看尚可&#xff0c;连续播放就会出现明显割裂&#xff0c;大量时间浪费在反复修改画面上。知漫剧&#xff08;zz.jiaxunai.cn&a…

作者头像 李华