[英]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
,一个Integer
或Double
(如果Character
是树的一个通用参数,那么它的 ASCII 码和将从sum()
返回sum()
方法)。
我需要执行各种操作,例如所有节点值的sum()
(还有插入、删除、搜索、最大值、最小值等)。
但我坚持让我的实现通用。 在sum()
方法中,行中出现错误
sum += current.value;
运算符 + 不能应用于 T。
我该如何解决?
算术运算符不能与任意类型一起使用,它们仅适用于数字基元及其包装类型。 因此,如果您需要生成您的逻辑,这不是可行的方法。
相反,您可以在Tree
类(或任何它的名称)的级别上定义一个BiFunction
类型的字段,它是一个需要两个参数的函数。 并使用此BinaryOperator
在遍历树时累积节点的值。
基于这个引用:
如果
Character
是树的通用参数,那么它的 ASCII 码总和将从sum()
方法返回
我假设您需要将sum()
方法的返回类型保持为double
。 由于根据您的作业要求,只需要支持三种泛型类型: Character
、 Integer
或Double
,这是可行的。
对于上面提到的BiFunction
,可以定义为BiFunction<T,Double,Double>
,其中前两个泛型参数T
和Double
表示函数的传入参数类型,最后一个类型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.