You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让MazeNode访问BST嵌套Node类的子节点与深度属性

问题描述

我实现了泛型二叉搜索树BST<E extends Comparable<E>>类,其中嵌套的protected Node类包含data、leftChild、rightChild、depth属性及相关方法;同时实现了存储标签和生命值的MazeNode类(实现Comparable接口);Maze类继承自BST<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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 03:17:05