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

已编写部分BinarySearchTree代码,求指导完成第二个实现文件

如何完成二叉搜索树(BinarySearchTree)的第二个实现文件?

嘿,我来帮你梳理下怎么搞定这个二叉搜索树的第二个实现文件~先看看你已经写的代码片段:

package u7a3;
/**
 * generic binary search-tree with integer keys.
 * Empty trees are encoded as null references.
 *
 * @param <T> The type of the things which are managed in the binary
 * search tree
 */
public class BinarySearchTree<T> {
    /**
     * The key by which the thing is refered to. Must be unique.
     */
    public int key;
    /**
     * The thing which is managed in the binary search tree.
     */
    // 这里你应该是要加一个泛型属性,比如 public T value;
}

首先得明确:你说的「第二个实现文件」,大概率是把二叉树的核心操作(插入、查找、删除、遍历等)和节点定义分开,让职责更清晰——第一个文件只做节点的结构定义,第二个文件专门实现操作逻辑。下面分步骤给你讲:

第一步:补全第一个文件的节点定义

先把第一个文件的BinarySearchTree类补全,它只需要负责描述树的节点结构,尽量做好封装(把成员变量设为private,提供getter/setter,避免外部随便修改key破坏树的结构):

package u7a3;

/**
 * generic binary search-tree with integer keys.
 * Empty trees are encoded as null references.
 *
 * @param <T> The type of the things which are managed in the binary
 * search tree
 */
public class BinarySearchTree<T> {
    private int key;
    private T value;
    private BinarySearchTree<T> left; // 左子树
    private BinarySearchTree<T> right; // 右子树

    // 构造方法:创建一个非空节点
    public BinarySearchTree(int key, T value) {
        this.key = key;
        this.value = value;
        this.left = null;
        this.right = null;
    }

    // Getter和Setter,保证封装性
    public int getKey() {
        return key;
    }

    public void setKey(int key) {
        this.key = key;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }

    public BinarySearchTree<T> getLeft() {
        return left;
    }

    public void setLeft(BinarySearchTree<T> left) {
        this.left = left;
    }

    public BinarySearchTree<T> getRight() {
        return right;
    }

    public void setRight(BinarySearchTree<T> right) {
        this.right = right;
    }
}

第二步:编写第二个文件的操作逻辑

新建一个比如叫BinarySearchTreeOperations的类,把二叉搜索树的所有核心操作都放在这里,用静态方法实现(因为操作是针对整个树的根节点,不需要实例化这个操作类):

package u7a3;

public class BinarySearchTreeOperations {

    // 1. 插入节点:递归实现,支持更新重复key的value
    public static <T> BinarySearchTree<T> insert(BinarySearchTree<T> root, int key, T value) {
        // 空树直接返回新节点
        if (root == null) {
            return new BinarySearchTree<>(key, value);
        }

        // 小于当前key,插入左子树
        if (key < root.getKey()) {
            root.setLeft(insert(root.getLeft(), key, value));
        }
        // 大于当前key,插入右子树
        else if (key > root.getKey()) {
            root.setRight(insert(root.getRight(), key, value));
        }
        // 等于当前key,更新value(也可以抛出异常提示重复)
        else {
            root.setValue(value);
        }

        return root;
    }

    // 2. 查找节点:根据key找对应的值
    public static <T> T search(BinarySearchTree<T> root, int key) {
        // 空树或者找到目标节点,返回结果
        if (root == null || root.getKey() == key) {
            return root != null ? root.getValue() : null;
        }

        // 小于当前key,往左找;否则往右找
        return key < root.getKey() ? search(root.getLeft(), key) : search(root.getRight(), key);
    }

    // 3. 删除节点:最复杂的操作,分三种情况处理
    public static <T> BinarySearchTree<T> delete(BinarySearchTree<T> root, int key) {
        if (root == null) {
            return null;
        }

        // 找到要删除的节点
        if (key < root.getKey()) {
            root.setLeft(delete(root.getLeft(), key));
        } else if (key > root.getKey()) {
            root.setRight(delete(root.getRight(), key));
        } else {
            // 情况1:叶子节点(没有子节点),直接删除
            if (root.getLeft() == null && root.getRight() == null) {
                return null;
            }
            // 情况2:只有一个子节点,返回这个子节点代替当前节点
            else if (root.getLeft() == null) {
                return root.getRight();
            } else if (root.getRight() == null) {
                return root.getLeft();
            }
            // 情况3:有两个子节点,找右子树的最小节点(后继节点)代替当前节点
            else {
                BinarySearchTree<T> minRightNode = findMinNode(root.getRight());
                // 替换当前节点的key和value
                root.setKey(minRightNode.getKey());
                root.setValue(minRightNode.getValue());
                // 删除那个后继节点
                root.setRight(delete(root.getRight(), minRightNode.getKey()));
            }
        }

        return root;
    }

    // 辅助方法:找树中的最小节点(最左节点)
    private static <T> BinarySearchTree<T> findMinNode(BinarySearchTree<T> node) {
        while (node.getLeft() != null) {
            node = node.getLeft();
        }
        return node;
    }

    // 4. 中序遍历:升序输出所有节点的key和value
    public static <T> void inorderTraversal(BinarySearchTree<T> root) {
        if (root != null) {
            inorderTraversal(root.getLeft());
            System.out.printf("Key: %d, Value: %s%n", root.getKey(), root.getValue());
            inorderTraversal(root.getRight());
        }
    }
}

第三步:测试使用示例

你可以写个测试类验证功能,比如:

package u7a3;

public class BstTest {
    public static void main(String[] args) {
        BinarySearchTree<String> root = null;

        // 插入节点
        root = BinarySearchTreeOperations.insert(root, 5, "Apple");
        root = BinarySearchTreeOperations.insert(root, 3, "Banana");
        root = BinarySearchTreeOperations.insert(root, 7, "Cherry");

        // 查找节点
        System.out.println("查找key=3的值:" + BinarySearchTreeOperations.search(root, 3));

        // 中序遍历
        System.out.println("中序遍历结果:");
        BinarySearchTreeOperations.inorderTraversal(root);

        // 删除节点
        root = BinarySearchTreeOperations.delete(root, 5);
        System.out.println("删除key=5后的中序遍历:");
        BinarySearchTreeOperations.inorderTraversal(root);
    }
}

这样拆分的好处是职责单一:BinarySearchTree只负责节点的结构,BinarySearchTreeOperations负责所有业务操作,代码更清晰,也方便后续维护扩展。

内容的提问来源于stack exchange,提问作者Jo An

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:49:53