如何让MazeNode访问BST嵌套Node类的子节点与深度属性
问题描述
我实现了泛型二叉搜索树BST<E extends Comparable<E>>类,其中嵌套的protected Node类包含data、leftChild、rightChild、depth属性及相关方法;同时实现了存储标签和生命值的MazeNode类(实现ComparableBST<MazeNode>,其play()方法用于寻找英雄可通行的最深叶子节点路径。
现在遇到的问题是:play()方法中MazeNode类型的变量无法访问BST嵌套Node类的leftChild、rightChild和depth属性。要求不能将BST的Node类改为泛型,也不能新建类,该如何解决?
解决方案
核心问题是你把BST的嵌套Node节点容器和存储业务数据的MazeNode实体搞混了:Iterator返回的是Node里的data(也就是MazeNode对象),而不是Node节点本身,自然访问不到Node的leftChild、rightChild、depth属性。
按照要求,不修改Node类为泛型、不新建类,可通过以下方式解决:
1. 在BST类中新增protected访问方法
给BST类添加一组protected方法,让子类Maze可以合法访问Node节点的关系和属性:
- 根据data查找对应的Node节点
- 获取节点的左/右子节点
- 获取节点的深度
2. 修改Maze类的play()方法逻辑
不再直接用Iterator返回的MazeNode去访问节点属性,而是通过BST提供的方法拿到对应的Node节点后再操作。
修改后的代码
BST类(新增方法)
public class BST<E extends Comparable<E>> implements Iterable<E> { protected class Node { E data; Node leftChild; Node rightChild; int depth; public Node(E data) { this.data = data; this.leftChild = null; this.rightChild = null; this.depth = 0; } public int getDepth(){ return this.depth; } public void setDepth(int depth){ this.depth = depth; } } protected Node root; // 新增:根据data查找对应的Node节点(假设BST中data唯一) protected Node findNode(E data) { Node current = root; while (current != null) { int cmp = data.compareTo(current.data); if (cmp == 0) { return current; } else if (cmp < 0) { current = current.leftChild; } else { current = current.rightChild; } } return null; } // 新增:获取节点的左子节点 protected Node getLeftChild(Node node) { return node != null ? node.leftChild : null; } // 新增:获取节点的右子节点 protected Node getRightChild(Node node) { return node != null ? node.rightChild : null; } // 新增:获取节点的深度 protected int getNodeDepth(Node node) { return node != null ? node.getDepth() : 0; } // 原有的Iterable实现及其他方法保留 @Override public Iterator<E> iterator() { // 保留原实现 return null; } // 原有的preOrderIterator方法保留 public Iterator<E> preOrderIterator() { // 保留原实现 return null; } }
Maze类(修改play()方法)
public class Maze extends BST<MazeNode> { private int maxDepth = 0; public void play(Hero hero) { Iterator<MazeNode> pre1 = this.preOrderIterator(); int maxDepth = 0; // 第一步:遍历找到最大深度 while (pre1.hasNext()) { MazeNode data = pre1.next(); Node node = findNode(data); if (node != null && getLeftChild(node) == null && getRightChild(node) == null) { int depth = getNodeDepth(node); if (depth > maxDepth) { maxDepth = depth; } } } // 第二步:遍历寻找最深叶子节点的路径 Iterator<MazeNode> pre2 = this.preOrderIterator(); Stack<Node> nodeStack = new Stack<>(); // 改为存储Node节点 while (pre2.hasNext()) { MazeNode data = pre2.next(); Node currentNode = findNode(data); if (currentNode == null) continue; if (getLeftChild(currentNode) == null && getRightChild(currentNode) == null) { int currentDepth = getNodeDepth(currentNode); if (currentDepth == maxDepth && hero.getLives() >= 0) { // 输出路径:取出栈中Node的data属性 System.out.println(nodeStack.stream().map(n -> n.data).toArray()); // 调整路径并修改英雄生命值 while (!nodeStack.isEmpty() && !(getLeftChild(nodeStack.peek()) == currentNode || getRightChild(nodeStack.peek()) == currentNode)) { Node poppedNode = nodeStack.pop(); hero.editLife(-poppedNode.data.getLifePoints()); } } else if (currentDepth < maxDepth) { while (!nodeStack.isEmpty() && !(getLeftChild(nodeStack.peek()) == currentNode || getRightChild(nodeStack.peek()) == currentNode)) { Node poppedNode = nodeStack.pop(); hero.editLife(-poppedNode.data.getLifePoints()); } } } else { nodeStack.push(currentNode); hero.editLife(currentNode.data.getLifePoints()); } } } }
关键说明
- 彻底区分
Node(BST的节点容器)和MazeNode(业务数据):Iterator返回的是MazeNode,必须通过findNode方法找到对应的BST Node节点才能访问结构属性。 - 所有对节点关系和深度的操作都通过BST提供的protected方法完成,符合Java的访问权限规则。
- 栈改为存储Node节点,方便判断父子关系,需要业务数据时直接取Node的
data属性即可。
内容的提问来源于stack exchange,提问作者James Hou
相关产品推荐
相关产品推荐

