题目

Given a tree, you are supposed to tell if it is a complete binary tree.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<=20) which is the total number of nodes in the tree — and hence the nodes are numbered from 0 to N-1. Then N lines follow, each corresponds to a node, and gives the indices of the lef and right children of the node. If the child does not exist, a “-” will be put at the position. Any pair of children are separated by a space.

Output Specification:

For each case, print in one line “YES” and the index of the last node if the tree is a complete binary tree, or “NO” and the index of the root if not. There must be exactly one space separating the word and the number.

Sample Input 1:

9

7 8

– –

– –

– –

0 1

2 3

4 5

– –

– –

Sample Output 1:

YES 8

Sample Output 2:

8

– –

4 5

0 6

– –

2 3

– 7

– –

– –

Sample Output 2:

NO 1

题目分析

已知树所有节点的子节点信息,判断是否是完全二叉树,是打印YES+最后一个节点,否打印NO+根节点

解题思路

  1. 深度遍历树,将树中节点存储与数组中,根节点index=0,其左右子节点index分别为2i+1,2i+2
  2. 判断是否为完全二叉树

    2.1 方式一:判断前后节点index是否相差1(若使用数组存储判断数组中有没有浪费的空闲位置,因为完全二叉树使用数组存储时中间没有空闲位置)

    2.2 方式二:最大index==结点数n-1,若相等即为二叉树

    2.3 方式三:BFS借助队列层级遍历树,完全二叉树中间不会遇到NULL

Code

Code 01

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <queue>
  4. using namespace std;
  5. const int maxn = 30;
  6. bool isRoot[maxn]; // 结点是否是根结点
  7. struct Node {
  8. int left, right; // 左孩子和右孩子的下标
  9. } node[maxn]; // 二叉树结点静态数组
  10. // input函数输入数据
  11. int input() {
  12. char id[3];
  13. scanf("%s", id); // 输入结点编号
  14. if(id[0] == '-') {
  15. return -1; // 如果是'-',说明是空结点,返回-1
  16. } else {
  17. if(strlen(id) == 1) return id[0] - '0'; // 编号小于10
  18. else return (id[0] - '0') * 10 + (id[1] - '0'); // 编号大于等于10
  19. }
  20. }
  21. // findRoot函数找到根结点编号
  22. int findRoot(int n) {
  23. for(int i = 0; i < n; i++) {
  24. if(isRoot[i]) { // isRoot为true时直接返回根结点编号i
  25. return i;
  26. }
  27. }
  28. }
  29. // BFS函数判断完全二叉树,root为根结点编号,last是最后一个结点编号(注意引用),n为结点个数
  30. bool BFS(int root, int &last, int n) {
  31. queue<int> q; // 定义队列
  32. q.push(root); // 根结点入队
  33. while(n) { // 只要n不为0,即还没有访问完全部非空结点
  34. int front = q.front(); // 队首结点front
  35. q.pop(); // 弹出队首结点
  36. if(front == -1) return false; // 访问到空结点,一定是非完全二叉树
  37. n--; // 已访问的非空结点减少1
  38. last = front; // 记录最后一个非空结点编号
  39. q.push(node[front].left); // 左孩子入队(包括空结点)
  40. q.push(node[front].right); // 右孩子入队(包括空结点)
  41. }
  42. return true; // 已经访问完所有非空结点,还没有碰到空结点,一定是完全二叉树
  43. }
  44. int main() {
  45. int n;
  46. scanf("%d", &n); // 输入结点个数
  47. memset(isRoot, true, sizeof(isRoot)); //初始化所有结点都是根结点
  48. for(int i = 0; i < n; i++) { // 对每一个结点
  49. int left = input(), right = input(); // 输入左右孩子编号
  50. isRoot[left] = isRoot[right] = false; // 这两个编号一定不是根结点
  51. node[i].left = left; // 记录左孩子
  52. node[i].right = right; // 记录右孩子
  53. }
  54. int root = findRoot(n), last; // 寻找根结点root,定义最后一个结点last
  55. bool isCompleteTree = BFS(root, last, n); // 判断完全二叉树,同时记录最后一个结点last
  56. if(isCompleteTree) { // 如果是完全二叉树
  57. printf("YES %d\n", last); // 输出最后一个结点编号
  58. } else {
  59. printf("NO %d\n", root); // 否则输出根结点编号
  60. }
  61. return 0;
  62. }

Code 02

  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int maxn=20;
  6. int flag[maxn];
  7. struct node {
  8. int data;
  9. int index;
  10. int left=-1;
  11. int right=-1;
  12. } nds[maxn];
  13. void dfs(int root,int index) {
  14. if(root==-1)return;
  15. nds[root].index=index;
  16. dfs(nds[root].left,2*index+1);
  17. dfs(nds[root].right,2*index+2);
  18. }
  19. bool cmp(node &n1,node &n2){
  20. return n1.index<n2.index;
  21. }
  22. int main(int argc,char * argv[]) {
  23. int n;
  24. scanf("%d",&n);
  25. string f,r;
  26. for(int i=0; i<n; i++) {
  27. cin>>f>>r;
  28. nds[i].data=i;
  29. if(f!="-") {
  30. nds[i].left=stoi(f);
  31. flag[nds[i].left]=1;
  32. }
  33. if(r!="-") {
  34. nds[i].right=stoi(r);
  35. flag[nds[i].right]=1;
  36. }
  37. }
  38. //find root;
  39. int k=0;
  40. while(k<n&&flag[k]==1)k++;
  41. dfs(k,0);
  42. sort(nds,nds+n,cmp);
  43. /**
  44. 判断当前树是否为完全二叉树:
  45. 方式一:遍历所有节点,前后节点index相差1
  46. 方式二:完全二叉树的所有节点最大index为n
  47. */
  48. bool iscbt=true;
  49. for(int i=1; i<n; i++) {
  50. if(nds[i].index-nds[i-1].index!=1) {
  51. iscbt=false;
  52. }
  53. }
  54. if(iscbt)printf("YES %d",nds[n-1].data);
  55. else printf("NO %d", nds[0].data);
  56. return 0;
  57. }

Code 03

  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int maxn=20;
  6. int flag[maxn];
  7. struct node {
  8. int left=-1;
  9. int right=-1;
  10. } nds[maxn];
  11. int max_n,max_i;
  12. void dfs(int root,int index) {
  13. if(root==-1)return;
  14. if(max_i<index) {
  15. max_i=index;
  16. max_n=root;
  17. }
  18. dfs(nds[root].left,2*index+1);
  19. dfs(nds[root].right,2*index+2);
  20. }
  21. int main(int argc,char * argv[]) {
  22. int n;
  23. scanf("%d",&n);
  24. string f,r;
  25. for(int i=0; i<n; i++) {
  26. cin>>f>>r;
  27. if(f!="-") {
  28. nds[i].left=stoi(f);
  29. flag[nds[i].left]=1;
  30. }
  31. if(r!="-") {
  32. nds[i].right=stoi(r);
  33. flag[nds[i].right]=1;
  34. }
  35. }
  36. //find root;
  37. int k=0;
  38. while(k<n&&flag[k]==1)k++;
  39. dfs(k,0);
  40. /**
  41. 判断当前树是否为完全二叉树:
  42. 方式一:遍历所有节点,前后节点index相差1
  43. 方式二:完全二叉树的所有节点最大index为n
  44. */
  45. if(max_i==n-1)printf("YES %d",max_n);
  46. else printf("NO %d", k);
  47. return 0;
  48. }

PAT Advanced 1110 Complete Binary Tree (25) [完全⼆叉树]的更多相关文章

  1. [二叉树建树&完全二叉树判断] 1110. Complete Binary Tree (25)

    1110. Complete Binary Tree (25) Given a tree, you are supposed to tell if it is a complete binary tr ...

  2. PAT甲级——1110 Complete Binary Tree (完全二叉树)

    此文章同步发布在CSDN上:https://blog.csdn.net/weixin_44385565/article/details/90317830   1110 Complete Binary ...

  3. PAT 甲级 1110 Complete Binary Tree

    https://pintia.cn/problem-sets/994805342720868352/problems/994805359372255232 Given a tree, you are ...

  4. 1110. Complete Binary Tree (25)

    Given a tree, you are supposed to tell if it is a complete binary tree. Input Specification: Each in ...

  5. 1110 Complete Binary Tree (25 分)

    Given a tree, you are supposed to tell if it is a complete binary tree. Input Specification: Each in ...

  6. PAT (Advanced Level) 1110. Complete Binary Tree (25)

    判断一棵二叉树是否完全二叉树. #include<cstdio> #include<cstring> #include<cmath> #include<vec ...

  7. PAT甲题题解-1110. Complete Binary Tree (25)-(判断是否为完全二叉树)

    题意:判断一个节点为n的二叉树是否为完全二叉树.Yes输出完全二叉树的最后一个节点,No输出根节点. 建树,然后分别将该树与节点树为n的二叉树相比较,统计对应的节点个数,如果为n,则为完全二叉树,否则 ...

  8. 【PAT甲级】1110 Complete Binary Tree (25分)

    题意: 输入一个正整数N(<=20),代表结点个数(0~N-1),接着输入N行每行包括每个结点的左右子结点,'-'表示无该子结点,输出是否是一颗完全二叉树,是的话输出最后一个子结点否则输出根节点 ...

  9. 1110 Complete Binary Tree

    1110 Complete Binary Tree (25)(25 分) Given a tree, you are supposed to tell if it is a complete bina ...

随机推荐

  1. leetcode1 twoSum

    """ Given an array of integers, return indices of the two numbers such that they add ...

  2. Ceph 概念理解

    简介 Ceph是一个可靠地.自动重均衡.自动恢复的分布式存储系统,根据场景划分可以将Ceph分为三大块,分别是对象存储.块设备存储和文件系统服务. 在虚拟化领域里,比较常用到的是Ceph的块设备存储, ...

  3. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-forward

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  4. msf自动连接postgresql配置

    今天做了一下msf连接数据库的配置,中间碰到了一些坑点这里就不详细叙述了,开始正确的操作方式. 首先对postgresql进行配置以方便连接. root@kali:~# service postgre ...

  5. FC 与 FB 与 OB 的区别,时间标记冲突与一致性检查 有详细的步骤

    关键字1 组织块的程序是由用户自己编写. 关键字2 时间标记冲突与一致性检查 有详细的步骤. 关键字3 FC 与 FB 与 OB 的区别?   (一)功能 功能块 区别 ? FB 和FC均为 用户编写 ...

  6. java 三羊献瑞

    三羊献瑞 观察下面的加法算式: 其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字. 请你填写"三羊献瑞"所代表的4位数字(答案唯一),不要填写任何多余内容. public ...

  7. Mysql自动备份与还原 转

    Mysql自动备份与还原 一.自动备份:将以下代码保存为*.bat批处理脚本,然后再添加Windows定时作业,如每天凌晨2点执行:set s=%date:~0,4%%date:~5,2%%date: ...

  8. cf 762C. Two strings

    因为要删去1个串(读错题),所以就直接二分搞就好了. 需要预处理出2个分别从头到尾,或从尾到头需要多长a串的数组,然后二分删去多长就好了. #include<bits/stdc++.h> ...

  9. 一百一十二、SAP的OO-ALV之六,复制一个工程的工具栏到另外一个工程的工具栏

    一.我们输入SE38,查看一个SAP的标准查询 二.可以看到这个程序拥有一个标准的工具栏 三.我们来到, 输入这个程序名,再点状态 四.把工具栏复制过来 五.弹出的窗口点对勾 六.系统提示已经复制 七 ...

  10. 经验分享:如何搞定Personal Statement?

    最近又到申请季啦,如何自己DIY申请,如何准备文书成为众多留学生关心的问题.不管是你申请本科,硕士,还是博士,相信这篇文章都能帮助到你.下面来说一下文书中一个很重要的组成,就是个人陈述Personal ...