gpt4 book ai didi

java - 使用泛型类在 Java 中进行树遍历

转载 作者:搜寻专家 更新时间:2023-11-01 03:05:28 25 4
gpt4 key购买 nike

准确地说,我正在尝试压平一棵树,并且一直在尝试使用通用函数获取通用类中私有(private)属性的值。

我附上了类来展示树的结构。但它看起来像这样:

  /|\
1 | 6
/|\
5 4 9

我将在最后粘贴我的尝试。首先,让我介绍一下类(class):

Triple 简单地存储相同类型的三个值。

public class Triple<V> {
private final V l, m, r;
public Triple(V l, V m, V r) {
this.l = l;
this.m = m;
this.r = r;
}
public V left() { return l; }
public V middle() { return m; }
public V right() { return r; }
}

直观的界面:

public interface Function<P, R> {
R apply(P p);
}

现在,对于一个棘手的类。这只是一种类型,它存储两种类型值的 EitherOr 之一,但不能同时存储两者。

public class EitherOr<A,B> {
// Constructs a left-type EitherOr
public static <A> EitherOr left(A a) {
return new EitherOr(a, null);
}
// Constructs a right-type EitherOr
public static <B> EitherOr right(B b) {
return new EitherOr(null, b);
}
private final A a;
private final B b;

private EitherOr(A a, B b) {
this.a = a; this.b = b;
}

public<T> T ifLeft(Function<A,T> f) {
return f.apply(a);
}

public<T> T ifRight(Function<B,T> f) {
return f.apply(b);
}

public boolean isLeft() {
return b == null;
}
}

我知道这会很长,但请耐心等待。这个类实现了树结构。

public interface Tree<T> {
EitherOr<T, Triple<Tree<T>>> get();

static final class Leaf<T> implements Tree<T> {
public static <T> Leaf<T> leaf (T value) {
return new Leaf<T>(value);
}

private final T t;

public Leaf(T t) { this.t = t; }

@Override
public EitherOr<T, Triple<Tree<T>>> get() {
return EitherOr.left(t);
}
}

static final class Node<T> implements Tree<T> {
public static <T> Tree<T> tree (T left, T middle, T right) {
return new Node<T>(Leaf.leaf(left), Leaf.leaf(middle), Leaf.leaf(right));
}

private final Triple<Tree<T>> branches;

public Node(Tree<T> left, Tree<T> middle, Tree<T> right) {
this.branches = new Triple<Tree<T>>(left, middle, right);
}

@Override
public EitherOr<T, Triple<Tree<T>>> get() {
return EitherOr.right(branches);
}
}
}

好的。这是我的扁平化想法:

public class MyFlattenTree<T> implements FlattenTree<T> {
public List<T> flattenInOrder(Tree<T> tree) {
List<T> list = new ArrayList<T>();
EitherOr<T, Triple<Tree<T>>> EitherOr;
EitherOr = tree.get();
// it is a leaf
if (EitherOr.isLeft()) {
// This is where the problem lies
// I don't how to get the value using a function f
list.add((T) EitherOr.ifLeft(f));
return list;
}
else {
// basically recursively go through the tree somehow
}
return null;
}
}

正如我所说,我坚持尝试使用 Function 接口(interface)检索 EitherOr 类中的值。我正在考虑实现 Function 接口(interface)并为“apply”编写一个函数来获取值,但我不确定该怎么做。任何帮助,将不胜感激。谢谢!

最佳答案

所以,这是你的 flattenInOrder方法:

public List<T> flattenInOrder(final Tree<T> tree) {
final EitherOr<T, Triple<Tree<T>>> EitherOr = tree.get();
if (EitherOr.isLeft()) {
return Collections.singletonList(EitherOr.ifLeft(this.ifLeftFunction));
}

return EitherOr.ifRight(this.ifRightFunction);
}

很简单,假设:

  • ifLeftFunction产生单个元素(因为 EitherOr<T, Triple<Tree<T>>> 有单个 T elem' 如果它是“左”)

...和:

  • ifRightFunction产生一个元素集合(因为 EitherOr<T, Triple<Tree<T>>> 有一个 T 元素的列表,如果它是“正确的”)

现在让我们看看这些函数:

ifLeftFunction是...基本的。我想提取一个 T来自... T .

final Function<T, T> ifLeftFunction = new Function<T, T>() {

@Override
public T apply(final T t) {
return t;
}
};

ifRightFunction稍微复杂一点:它必须是递归的并收集所有 T来自它正在浏览的树:

final Function<Triple<Tree<T>>, List<T>> ifRightFunction = new Function<Triple<Tree<T>>, List<T>>() {

@Override
public List<T> apply(final Triple<Tree<T>> t) {
final List<T> res = new ArrayList<>();
res.addAll(MyFlattenTree.this.flattenInOrder(t.left()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.middle()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.right()));
return res;
}
};

然后...你就完成了!


示例工作代码:

public class MyFlattenTree<T> {

private final Function<Triple<Tree<T>>, List<T>> ifRightFunction = new Function<Triple<Tree<T>>, List<T>>() {

@Override
public List<T> apply(final Triple<Tree<T>> t) {
final List<T> res = new ArrayList<>();
res.addAll(MyFlattenTree.this.flattenInOrder(t.left()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.middle()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.right()));
return res;
}
};

private final Function<T, T> ifLeftFunction = new Function<T, T>() {

@Override
public T apply(final T t) {
return t;
}
};

public static void main(final String[] args) {
final Tree<String> tree = new Node<>(new Leaf<>("1"), new Node<>(new Leaf<>("5"), new Leaf<>("4"), new Leaf<>("9")), new Leaf<>("6"));
System.out.println(new MyFlattenTree<String>().flattenInOrder(tree));
}

public List<T> flattenInOrder(final Tree<T> tree) {
final EitherOr<T, Triple<Tree<T>>> EitherOr = tree.get();
if (EitherOr.isLeft()) {
return Collections.singletonList(EitherOr.ifLeft(this.ifLeftFunction));
}

return EitherOr.ifRight(this.ifRightFunction);
}
}

请注意,我正在创建准确的 Tree您在 main 中的问题中作为示例方法在这里:

public static void main(final String[] args) {
final Tree<String> tree = new Node<>(new Leaf<>("1"), new Node<>(new Leaf<>("5"), new Leaf<>("4"), new Leaf<>("9")), new Leaf<>("6"));
System.out.println(new MyFlattenTree<String>().flattenInOrder(tree));
}

输出:[1, 5, 4, 9, 6]


干杯;)

关于java - 使用泛型类在 Java 中进行树遍历,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24420455/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com