华为OD机试真题中的"计算三叉搜索树的高度"是一道考察数据结构和算法能力的题目。三叉搜索树是一种特殊的树结构,其中每个节点有三个子节点:左子节点、中子节点和右子节点。在插入新节点时,会根据节点值与待插入值之间的差值关系,决定新节点应该插入到哪个子树中。
题目描述
每个节点都存有一个数,当插入一个新的数时,从根节点向下寻找,直到找到一个合适的空节点插入。查找的规则是:
- 如果数小于节点的数减去500,则将数插入节点的左子树。
- 如果数大于节点的数加上500,则将数插入节点的右子树。
- 否则,将数插入节点的中子树。
给你一系列数,请按以上规则,按顺序将数插入树中,构建出一棵三叉搜索树,最后输出树的高度(根节点的高度为1)。
输入描述
- 第一行为一个数N,表示有N个数,1 ≤ N ≤ 10000。
- 第二行为N个空格分隔的整数,每个数的范围为[1,10000]。
输出描述
输出树的高度(根节点的高度为1)。
解题思路
-
定义节点类:
- 创建一个
Node
类来表示三叉搜索树的节点,每个节点包含一个整数值val
和三个子节点指针left
、mid
、right
。
- 创建一个
-
插入节点:
- 编写一个插入函数,该函数接受当前节点和待插入的值作为参数。根据插入规则,递归地向下寻找合适的子节点进行插入。
-
计算树的高度:
- 在插入节点的过程中,可以记录当前节点的深度,从而得到树的最大深度,即树的高度。
- 另一种方法是,在插入完成后,从根节点开始递归地计算树的高度,通过比较左右中子树的高度并加1来得到当前节点的高度。
-
主函数:
- 读取输入,创建根节点,并依次插入每个数。
- 插入完成后,计算并输出树的高度。
5.画个图?
java
1000
/ | \
null 500 1500
| \
300 2000
\
2500
示例代码(java)
java
import lombok.Data;
@Data
public class TriNode {
private int val;
public TriNode left;
public TriNode mid;
public TriNode right;
public TriNode(int val) {
this.val = val;
this.left = this.mid = this.right = null;
}
}
java
import cn.gov.test.gt4.swjggl.vo.TriNode;
/**
* 1000
* / | \
* null 500 1500
* | \
* 300 2000
* \
* 2500
* *
* 三叉搜索树类
* 该树根据节点值与500的比较结果,将节点插入到树中的适当位置
* 并提供了计算树高度的方法
*/
public class TriSearchTree {
// 根节点
private TriNode root;
/**
* 默认构造函数,初始化根节点为null
*/
public TriSearchTree() {
this.root = null;
}
/**
* 插入函数,递归地将新节点插入到三叉搜索树中
*
* @param node 当前节点
* @param val 要插入的新节点的值
* @return 插入新节点后的子树的根节点
*/
private TriNode insert(TriNode node, int val) {
// 当前节点为空,创建并返回新节点
if (node == null) {
return new TriNode(val);
}
// 根据新节点的值与当前节点的值的比较,决定插入的方向
if (val < node.getVal() - 500) {
// 新节点的值小于当前节点的值减去500,插入左子树
node.setLeft(insert(node.getLeft(), val));
} else if (val > node.getVal() + 500) {
// 新节点的值大于当前节点的值加上500,插入右子树
node.setRight(insert(node.getRight(), val));
} else {
// 新节点的值在当前节点的值加减500范围内,插入中间子树
node.setMid(insert(node.getMid(), val));
}
// 返回插入新节点后的当前节点
return node;
}
/**
* 计算树的高度
*
* @param node 树的根节点
* @return 树的高度
*/
private int getHeight(TriNode node) {
// 如果根节点为空,表示树为空,返回高度0
if (node == null) {
return 0;
}
// 递归计算左子树的高度
int leftHeight = getHeight(node.left);
// 递归计算中子树的高度
int midHeight = getHeight(node.left);
// 递归计算右子树的高度
int rightHeight = getHeight(node.right);
// 返回最大子树高度加1作为当前节点的高度
return 1 + Math.max(Math.max(leftHeight, midHeight), rightHeight);
}
/**
* 外部调用接口,用于插入新节点
*
* @param val 要插入的新节点的值
*/
public void insert(int val) {
root = insert(root, val);
}
/**
* 外部调用接口,用于获取树的高度
*
* @return 树的高度
*/
public int getHeight() {
return getHeight(root);
}
/**
* 主函数,用于测试三叉搜索树的插入和高度计算功能
*
* @param args 命令行参数
*/
public static void main(String[] args) {
TriSearchTree tree = new TriSearchTree();
// 示例输入
int[] nums = {1000, 500, 2000, 300, 1500, 2500};
for (int num : nums) {
tree.insert(num);
}
// 输出树的高度
System.out.println("三叉搜索树的高度: " + tree.getHeight());
}
}
注意事项
- 在实现时,要注意处理空节点和边界情况。
- 对于大数据集,要注意算法的时间复杂度和空间复杂度,以避免超时或内存溢出。
- 在实际编程中,可能还需要添加一些额外的输入验证和错误处理机制来确保程序的健壮性。