PAT 甲级 1115 Counting Nodes in a BST (二叉排序树)(c++版)(附代码注释)

1115 Counting Nodes in a BST (30 分)

原文链接:http://kakazai.cn/index.php/Kaka/Pat/query/id/205

题目

题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805355987451904

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than or equal to the node’s key.
  • The right subtree of a node contains only nodes with keys greater than the node’s key.
  • Both the left and right subtrees must also be binary search trees.

Insert a sequence of numbers into an initially empty binary search tree. Then you are supposed to count the total number of nodes in the lowest 2 levels of the resulting tree.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤1000) which is the size of the input sequence. Then given in the next line are the N integers in [−10001000] which are supposed to be inserted into an initially empty binary search tree.

Output Specification:

For each case, print in one line the numbers of nodes in the lowest 2 levels of the resulting tree in the format:

n1 + n2 = n

where n1 is the number of nodes in the lowest level, n2 is that of the level above, and n is the sum.

Sample Input:

9
25 30 42 16 20 20 35 -5 28

Sample Output:

2 + 4 = 6

题意分析

  • 题意

二叉排序树的递归定义是1)左子树的所有结点的值都小于等于根结点的值;2)右子树的所有结点的值都大于根结点的值;3)左右子树也是一棵二叉排序树

将一个序列建成二叉排序树,输出其最后两层的结点的个数。

  • 分析

对二叉排序树进行建树,建树时要符合左小右大,建树过程中记录好每个结点的层次和每个层次的结点数,并且记录好最大的层数,按要求输出即可。

知识点与坑点

  • 知识点

1)二叉排序树,

  • 坑点

1)设计结点对应的数组下标为[1,n],则下标0可代表空结点。但若设计为[0,n],则下标0不可以代表空结点

一、递归法

算法思路

1 在二叉排序树建树时,将比当前结点小或等的往左边插,大的往右边插。

2 安放好每个点的同时,记录其层数,并统计该层上的结点数目。

3 记录好最大的层数,最后输出倒数两层的结点数。

代码-c++版
#include <iostream>
#include<cstdio>
using namespace std;
const int maxn = 1001;	//最多有1000个结点

/* 关键变量 */ 
int a[maxn],depth[maxn];		//存储序列;每层结点数 
int c[maxn][2];	//结点的左右孩子的下标,0代表空结点 
int maxd = 0;	//该树的总层数 

/* 二叉排序建树 */ 
void build(int &cur, int p, int d) {	
//将待插入的元素a[p]和当前结点a[cur]比较,d为a[cur]的层数
 
    if (cur == 0) {	//cur是空结点,则可存放p
        cur = p;	 
        depth[d]++;	//cur所在的层数结点个数增加 
        
        if (d > maxd) {	//更新最大层数 
            maxd = d;
        }
        return;
    }
    //cur处有结点
    if (a[p] <= a[cur]){ //如果元素比当前结点小或等 
		build(c[cur][0], p, d + 1);	//往当前结点的左子树比较 
	}
    else {
	build(c[cur][1], p, d + 1);//否则,往右子树比较 
	} 
}
int main() {
	int n; 
    scanf("%d", &n);

	int root = 0;	 //一开始根结点的位置是空的 
    for (int i = 1; i <= n; i++) { //逐步插入结点 
        scanf("%d", &a[i]);
        build(root, i, 1);	//根结点位于第1层 
    }
    
  /* 按要求输出 */
    printf("%d + %d = %d\n", depth[maxd], depth[maxd - 1], depth[maxd] + depth[maxd - 1]);
    return 0;
}
代码-python版

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值