L2-3 二叉搜索树的2层结点统计 (25 分)
二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树:若它的左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。
将一系列数字按给定顺序插入一棵初始为空的二叉搜索树,你的任务是统计结果树中最下面 2 层的结点数。
输入格式:输入在第一行给出一个正整数 N (≤1000),为插入数字的个数。第二行给出 N 个 [−1000,1000] 区间内的整数。数字间以空格分隔。
输出格式:在一行中输出最下面 2 层的结点总数。
输入样例:9
25 30 42 16 20 20 35 -5 28
输出样例:6
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Scanner;
public class Main {
//去重地存储层数且会自动排序,它的长度(set.size)就是最下一层
static HashSet<Integer> set = new HashSet<>();
static int sum = 0; //统计最下两层的结点总数
public static void main(String[] args) throws IOException {
//通过字符流输入可以大大节省数据输入所花的时间--有时可以避免 运行超时
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String n = bf.readLine();
String[] s = bf.readLine().split(" ");
Tree tree = new Tree(Integer.parseInt(s[0]),1);
set.add(tree.floors);
for(int i = 1;i<s.length;i++) {
insertValue(Integer.parseInt(s[i]),tree);
}
int m = 0;
traverseTree(tree);
System.out.println(sum);
}
//往树中按二叉排序树(左子树所有值<=本结点 值,右子树所有值>本结点值)的规则添加结点到适合位置
private static void insertValue(int num, Tree tree) {
//值<=本结点的值,则往左子树方向(遍历)插入
if(num <= tree.value) {
if(tree.left==null) //如果左子树为空,则直接添加左子树
tree.left = new Tree(num,tree.floors+1);
else //如果左子树不为空,则递归左子树(递归遍历左子树)
insertValue(num,tree.left);
}
//值>本结点的值,则往右子树方向(遍历)插入
else {
if(tree.right == null) //如果右子树为空,则直接添加右子树
tree.right = new Tree(num,tree.floors+1);
else //(递归遍历右子树)
insertValue(num, tree.right);
}
set.add(tree.floors+1); //添加层数(会自动去重)
}
//DBF利用递归遍历树 ---> 先序遍历(先中,再左,后右)
private static void traverseTree(Tree tree) {
if(tree==null)
return;
if(tree.floors == set.size()-1 || tree.floors == set.size())
sum++;
// System.out.println(tree.value+" "+tree.floors); //先中
traverseTree(tree.left); //再遍历左子树
traverseTree(tree.right); //后遍历右子树
}
}
class Tree{
int value; //数值
int floors; //本结点所在的层数(从上往下1-n)
Tree right; //右子树
Tree left; //左子树
public Tree(int value, int floors) {
this.value = value;
this.floors = floors;
}
}