繁体   English   中英

使二进制搜索树通用

[英]Making a Binary search Tree Generic

public double sum(TreeNode root){
    Queue<TreeNode> queue = new ArrayDeque<>();
    double sum = 0;
    if(root!=null){
        queue.add(root);
    }
    while(!queue.isEmpty()){
        int size = queue.size();
        for (int i = 0; i < size; i++) {
            TreeNode current = queue.remove();
            sum += current.value;
            if(current.leftChild!=null)
                queue.add(current.leftChild);
            if(current.rightChild!=null)
                queue.add(current.rightChild);
        }
    }
    return sum;
}

现在我需要实现一个通用的二叉搜索树,它可以在节点的value字段中存储一个Character ,一个IntegerDouble (如果Character是树的一个通用参数,那么它的 ASCII 码和将从sum()返回sum()方法)。

我需要执行各种操作,例如所有节点值的sum() (还有插入、删除、搜索、最大值、最小值等)。

但我坚持让我的实现通用。 sum()方法中,行中出现错误

sum += current.value;

运算符 + 不能应用于 T。

我该如何解决?

算术运算符不能与任意类型一起使用,它们仅适用于数字基元及其包装类型。 因此,如果您需要生成您的逻辑,这不是可行的方法。

相反,您可以在Tree类(或任何它的名称)的级别上定义一个BiFunction类型的字段,它是一个需要两个参数的函数 并使用此BinaryOperator在遍历树时累积节点的值。

基于这个引用:

如果Character是树的通用参数,那么它的 ASCII 码总和将从sum()方法返回

我假设您需要将sum()方法的返回类型保持为double 由于根据您的作业要求,只需要支持三种泛型类型: CharacterIntegerDouble ,这是可行的。

对于上面提到的BiFunction ,可以定义为BiFunction<T,Double,Double> ,其中前两个泛型参数TDouble表示函数的传入参数类型,最后一个类型Double指定返回类型。 以下是此类功能的实现示例:

BiFunction<Double, Double, Double> intMerger = Double::sum;
BiFunction<Integer, Double, Double> intMerger = (i, d) -> i + d;
BiFunction<Character, Double, Double> intMerger = (c, d) -> c + d;

此外,由于您需要在通用树中执行二进制搜索等操作,因此您需要将通用参数T定义为扩展Comparable接口,或者提供一个Comparator否则在实现时您将无法确定哪个值更大/更小二进制搜索,或查找最小/最大值)。 由于应支持的所有类型都是可比较的,因此您可以使用第一个选项并将 Generic 参数定义为T extends Comparable<T> ,这在简单的英语中意味着:知道如何比较自身的东西。

因此,您可能会有这样的结果:

public class MyTree<T extends Comparable<T>> {
    private final BiFunction<T, Double, Double> merger;

    public MyTree(BiFunction<T, Double, Double> merger) {
        this.merger = merger;
    }

    public double sum(TreeNode<T> root) {
        double total = 0;
        if (root == null) return total;
        
        Queue<TreeNode<T>> queue = new ArrayDeque<>();
        queue.add(root);
        
        while (!queue.isEmpty()) {
            int size = queue.size();
            TreeNode<T> current = queue.remove();

            total = merger.apply(current.value, total);
            
            if (current.leftChild != null) queue.add(current.leftChild);
            if (current.rightChild != null) queue.add(current.rightChild);
        }
        return total;
    }
    
    private static class TreeNode<T extends Comparable<T>> {
        private T value;
        private TreeNode<T> leftChild;
        private TreeNode<T> rightChild;
        
        // constructor, etc.
    }
}

使用示例:

MyTree<Double> myTree1 = new MyTree<>(Double::sum);
MyTree<Integer> myTree2 = new MyTree<>((i, d) -> i + d);
MyTree<Character> myTree3 = new MyTree<>((c, d) -> c + d);

注意:如果我所说的关于引入函数的内容对您来说看起来很陌生,请查看Oracle 提供的本教程

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM