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
    评论
当然可以!以下是使用C++和vector实现计数排序的示例代码: ```cpp #include <iostream> #include <vector> using namespace std; // 计数排序函数 void countingSort(vector<int>& arr) { int maxVal = *max_element(arr.begin(), arr.end()); // 找到数组中的最大值 int size = arr.size(); // 创建计数数组并初始化为0 vector<int> count(maxVal + 1, 0); // 统计每个元素出现的次数 for (int i = 0; i < size; i++) { count[arr[i]]++; } // 计算每个元素在排序后的数组中的位置 for (int i = 1; i <= maxVal; i++) { count[i] += count[i - 1]; } vector<int> output(size); // 创建输出数组 // 根据计数数组将元素放到正确的位置上 for (int i = size - 1; i >= 0; i--) { output[count[arr[i]] - 1] = arr[i]; count[arr[i]]--; } // 将排序后的数组赋值给原始数组 for (int i = 0; i < size; i++) { arr[i] = output[i]; } } // 测试计数排序算法 int main() { vector<int> arr = {4, 2, 2, 8, 3, 3, 1}; cout << "原始数组:"; for (int num : arr) { cout << num << " "; } countingSort(arr); cout << "\n排序后的数组:"; for (int num : arr) { cout << num << " "; } return 0; } ``` 以上代码中,`countingSort`函数用于实现计数排序算法。它首先找到数组中的最大值,然后创建一个计数数组并将其初始化为0。接下来,它遍历原始数组并统计每个元素的出现次数。然后,通过累加计数数组,计算每个元素在排序后的数组中的位置。最后,根据计数数组将元素放到正确的位置上,形成排序后的数组。 在`main`函数中,我们创建了一个测试数组,并调用`countingSort`函数对其进行排序。最后,打印原始数组和排序后的数组。 希望这个示例能够帮助到你!如果有任何疑问,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值