Java二叉树实现及核心操作方法开发求助
搞定Java二叉树的完整实现!
我来帮你解决这棵二叉树的实现问题,先梳理下原代码里的几个小问题,再逐个实现缺失的方法,保证和你的主类调用完全匹配:
原代码里的核心问题
depth方法定义了Tree tree参数,但主类调用的是无参的tree.depth(),需要调整方法签名smallest和biggest方法带参数,但主类调用的是无参版本,而且内部逻辑完全错误(比如用Tree.lhs访问类属性、nil是Python语法)add、exists、isDegenerate、toString都是空实现,需要补充逻辑- 原
depth方法的返回值是节点数,不符合注释里「深度是根到叶子的最大边数」的定义
完整实现代码
/** * 存储int类型值的二叉树。 */ class Tree { /** * 该树节点的值。 */ private int node; /** * 左子树。 */ private Tree lhs; /** * 右子树。 */ private Tree rhs; /** * 创建一个包含指定节点值的新树。 * @param node 该树节点的值。 */ public Tree(int node) { this.node = node; this.lhs = null; this.rhs = null; } /** * 向树中添加节点,拒绝重复值。 * @param insert 待插入的数值 */ public void add(int insert) { // 拒绝重复值 if (insert == this.node) { return; } // 插入左子树 if (insert < this.node) { if (this.lhs == null) { this.lhs = new Tree(insert); } else { this.lhs.add(insert); } } // 插入右子树 else { if (this.rhs == null) { this.rhs = new Tree(insert); } else { this.rhs.add(insert); } } } /** * 计算树的深度,定义为从根节点到叶子节点的最大边数。 * @return 树的深度 */ public int depth() { // 叶子节点深度为0(无任何子边) if (this.lhs == null && this.rhs == null) { return 0; } int leftDepth = lhs != null ? lhs.depth() : -1; int rightDepth = rhs != null ? rhs.depth() : -1; return Math.max(leftDepth, rightDepth) + 1; } /** * 在树中查找指定数值。 * @param wanted 待查找的数值 * @return 若数值存在返回true,否则返回false */ public boolean exists(int wanted) { // 当前节点匹配目标值 if (wanted == this.node) { return true; } // 目标值更小,递归左子树查找 if (wanted < this.node) { return this.lhs != null && this.lhs.exists(wanted); } // 目标值更大,递归右子树查找 else { return this.rhs != null && this.rhs.exists(wanted); } } /** * 查找树中的最小数值。 * @return 树中的最小数值 */ public int smallest() { // 二叉搜索树的最小值在最左侧节点 if (this.lhs == null) { return this.node; } return this.lhs.smallest(); } /** * 查找树中的最大数值。 * @return 树中的最大数值 */ public int biggest() { // 二叉搜索树的最大值在最右侧节点 if (this.rhs == null) { return this.node; } return this.rhs.biggest(); } /** * 判断树是否为退化树(每个节点最多有一个子节点)。 * @return 若为退化树返回true,否则返回false */ public boolean isDegenerate() { // 同时存在左右子树,直接判定为非退化树 if (this.lhs != null && this.rhs != null) { return false; } // 递归验证左子树 if (this.lhs != null) { return this.lhs.isDegenerate(); } // 递归验证右子树 if (this.rhs != null) { return this.rhs.isDegenerate(); } // 叶子节点符合退化树条件 return true; } /** * 将树格式化为可读字符串(括号表示法:根(左子树,右子树))。 * @return 格式化后的字符串 */ @Override public String toString() { String leftStr = lhs != null ? lhs.toString() : "null"; String rightStr = rhs != null ? rhs.toString() : "null"; return String.format("%d(%s,%s)", this.node, leftStr, rightStr); } } class Main { public static void main(String[] args) { Tree tree = new Tree(15); int[] set1 = {15, 21, 8, 41, 8, 5, 41, 33}; int[] set2 = {18, 45, 36, 19, 3, 24, 19, 10}; for (int i = 0; i < set1.length; i++) { tree.add(set1[i]); } System.out.println(tree.toString()); System.out.println("The depth of the tree is " + tree.depth() + "."); System.out.println("Does the number 8 exist in the tree? " + tree.exists(8)); System.out.println("Does the number 24 exist in the tree? " + tree.exists(24)); System.out.println(tree.smallest() + " is the smallest number in the tree. "); System.out.println(tree.biggest() + " is the biggest number in the tree. "); System.out.println("Is the tree degenerate? " + tree.isDegenerate()); for (int i = 0; i < set2.length; i++) { tree.add(set2[i]); } System.out.println(tree.toString()); System.out.println("The depth of the tree is " + tree.depth() + "."); System.out.println("Does the number 8 exist in the tree? " + tree.exists(8)); System.out.println("Does the number 24 exist in the tree? " + tree.exists(24)); System.out.println(tree.smallest() + " is the smallest number in the tree. "); System.out.println(tree.biggest() + " is the biggest number in the tree. "); System.out.println("Is the tree degenerate? " + tree.isDegenerate()); } }
关键方法说明
- add方法:遵循二叉搜索树规则,小于当前节点插左子树,大于插右子树,遇到重复值直接返回(拒绝重复)。
- depth方法:递归计算左右子树的深度,取最大值加1,确保返回的是边数(单个节点深度为0,符合注释定义)。
- exists方法:递归查找,根据数值大小选择左/右子树,子树为空则返回false。
- smallest/biggest方法:利用二叉搜索树的特性,最小值在最左节点,最大值在最右节点,递归到叶子节点即可。
- isDegenerate方法:判断每个节点是否同时存在左右子树,只要有一个节点满足,就不是退化树,否则递归验证子树。
- toString方法:用括号嵌套的格式展示树结构,空节点用
null标识,直观清晰。
运行主类后,你会看到每个方法的输出都符合预期,比如第一次插入set1后,树不是退化树;插入set2后,同样不会是退化树(因为有节点同时有左右子树)。
内容的提问来源于stack exchange,提问作者G Dawg
相关产品推荐
相关产品推荐

