[英]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;
}
Now I need to implement a generic binary search Tree which can store in the value
field of a node either a Character
, an Integer
or Double
(if Character
is a generic parameter of the Tree, then its ASCII code sum will be returned from the sum()
method).现在我需要实现一个通用的二叉搜索树,它可以在节点的
value
字段中存储一个Character
,一个Integer
或Double
(如果Character
是树的一个通用参数,那么它的 ASCII 码和将从sum()
返回sum()
方法)。
And I need to perform various operations, like sum()
of all the node's values (also insert, delete, search, maximum, minimum, etc.).我需要执行各种操作,例如所有节点值的
sum()
(还有插入、删除、搜索、最大值、最小值等)。
But I'm stuck on making my implementation generic.但我坚持让我的实现通用。 In the
sum()
method issues an error in the line在
sum()
方法中,行中出现错误
sum += current.value;
Operator + cannot be applied to T.
运算符 + 不能应用于 T。
How can I resolve it?我该如何解决?
Arithmetic operators can not be used with an arbitrary type, they are only applicable for numeric primitives and their wrapper types.算术运算符不能与任意类型一起使用,它们仅适用于数字基元及其包装类型。 So if you need to generify your logic, it not the way to go.
因此,如果您需要生成您的逻辑,这不是可行的方法。
Instead, you can define a field of type BiFunction
, which is a Function expecting two arguments, on the level of your Tree
class (or whatever its name).相反,您可以在
Tree
类(或任何它的名称)的级别上定义一个BiFunction
类型的字段,它是一个需要两个参数的函数。 And use this BinaryOperator
to accumulate the values of the nodes while traversing the tree.并使用此
BinaryOperator
在遍历树时累积节点的值。
Based on this quote:基于这个引用:
if
Character
is a generic parameter of the Tree, then its ASCII code sum will be returned from thesum()
method如果
Character
是树的通用参数,那么它的 ASCII 码总和将从sum()
方法返回
I assume that you need to keep the return type of the sum()
method as double
.我假设您需要将
sum()
方法的返回类型保持为double
。 Since according to the requirements of your assignment only three generic types: Character
, Integer
or Double
need to be supported, that's doable.由于根据您的作业要求,只需要支持三种泛型类型:
Character
、 Integer
或Double
,这是可行的。
For that the BiFunction
mentioned above, can be defined as BiFunction<T,Double,Double>
, where the first two generic parameters T
and Double
denote the types of incoming parameters of the function and the last type Double
specifies the return type.对于上面提到的
BiFunction
,可以定义为BiFunction<T,Double,Double>
,其中前两个泛型参数T
和Double
表示函数的传入参数类型,最后一个类型Double
指定返回类型。 Here are examples of implementation of such function:以下是此类功能的实现示例:
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;
Also, since you need to perform operations like binary search in your generic tree you need either define a generic parameter T
as extending Comparable
interface, or provide a Comparator
( otherwise you'll not be able to determine which value is greater/smaller while implementing a binary search, or finding min/max value ).此外,由于您需要在通用树中执行二进制搜索等操作,因此您需要将通用参数
T
定义为扩展Comparable
接口,或者提供一个Comparator
(否则在实现时您将无法确定哪个值更大/更小二进制搜索,或查找最小/最大值)。 Since all the types that should be supported are comparable, you can use the first option and define the Generic parameter as T extends Comparable<T>
, which means in plain English: something that knows how to compare itself.由于应支持的所有类型都是可比较的,因此您可以使用第一个选项并将 Generic 参数定义为
T extends Comparable<T>
,这在简单的英语中意味着:知道如何比较自身的东西。
So as a result, you might have something like this:因此,您可能会有这样的结果:
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.
}
}
Usage example:使用示例:
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);
Note: if what I was telling about introducing a Function looks alien to you have a look at this tutorial provided by Oracle .注意:如果我所说的关于引入函数的内容对您来说看起来很陌生,请查看Oracle 提供的本教程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.