Java 中有 3 children 的树的迭代器实现
Iterator implementation for tree with 3 children in Java
对于大学,我应该将接口迭代器实现为具有 3 Children 的树的内部 Class。
我对树的实现如下所示:
import java.util.*;
public class TernaerTree <E> {
private TernaerTree left;
private TernaerTree right;
private TernaerTree middle;
private E value;
public E getValue() {
return value;
}
public TernaerTree(TernaerTree left, TernaerTree middle, TernaerTree right, E value) {
this.left = left;
this.right = right;
this.middle = middle;
this.value = value;
}
public static void main(String [] args){
TernaerTree <String> baum = new TernaerTree<String>(new TernaerTree<String>(null,null,null,"Hallo"),new TernaerTree<String>(null,null,null,"Welt"),new TernaerTree<String>(null,null,null,"?"),"!");
}
public class WalkThroughIterator implements Iterator {
@Override
public boolean hasNext() {
}
@Override
public Object next() {
}
@Override
public void remove() {
throw new UnsupportedOperationException("remove() is not supported.");
}
}
}
现在我应该实现 WalkthroughIterator。它应该按以下顺序遍历树:左、中、右和节点本身。迭代器应该使用递归的子树迭代器。
在主要方法中,所有内容都应打印在屏幕上。
希望有人能帮助我。
谢谢,
托拜厄斯
我建议你让 TernaerTree 实现可迭代。那会让事情变得容易得多。您可以 return iterator() 中的 WalkThroughIterator 迭代器,您将为 iterable 实现该迭代器。这样就少了很多混乱。
那么你就可以把树的所有基本功能都作为TernaerTree的一部分。
最简单的方法(如果你不太关心复杂性/性能),你可以添加一个构造函数并按照你想要的递归顺序构建节点的线性 AST(例如,列表)。
public class WalkThroughIterator implements Iterator {
private List<E> values = new ArrayList<E>();
private int currentElement = 0;
public WalkThroughIterator(TernaerTree<E> tree) {
buildList(tree);
}
private void buildList(TernaerTree<E> node) {
if (node == null)
return;
buildList(node.left); //probably be best to add a getLeft() method etc
buildList(node.middle);
buildList(node.right);
values.add(node.getValue());
}
@Override
public boolean hasNext() {
return (currentElement < values.size());
}
@Override
public Object next() {
return values.get(currentElement++);
}
@Override
public void remove() {
throw new UnsupportedOperationException("remove() is not supported.");
}
}
然后只需将 getIterator
方法添加到您的树对象中即可:
public WalkThroughIterator getIterator() {
return new WalkThroughIterator(this);
}
或者简单地用根实例化一个新的 WalkThroughIterator
对象。
(顺便说一句,请注意,如果您让对象实现 Iterable
然后按照上面的建议实现,您可以使用 for-each 循环遍历树。)
这似乎可行 - 它使用 iterator
的列表来跟踪内部树。一旦所有这些都耗尽,它就会发出元素。
public class TernaerTree<E> implements Iterable<E> {
private TernaerTree left;
private TernaerTree middle;
private TernaerTree right;
private E value;
public E getValue() {
return value;
}
public TernaerTree(TernaerTree left, TernaerTree middle, TernaerTree right, E value) {
this.left = left;
this.middle = middle;
this.right = right;
this.value = value;
}
@Override
public Iterator<E> iterator() {
return new WalkThroughIterator();
}
public class WalkThroughIterator implements Iterator<E> {
// All the iterators of all of the sub-trees that weren't null.
List<Iterator<E>> iterators = new LinkedList<>();
// Have we delivered the element?
private boolean deliveredElement = false;
public WalkThroughIterator() {
// Is there a 'left' tree?
if (left != null) {
iterators.add(left.iterator());
}
// a middle
if (middle != null) {
iterators.add(middle.iterator());
}
// a right
if (right != null) {
iterators.add(right.iterator());
}
}
@Override
public boolean hasNext() {
// we've finished if we've delivered the element.
return !deliveredElement;
}
@Override
public E next() {
// First consume the iterators.
while (iterators.size() > 0) {
// Grab the first one.
Iterator<E> it = iterators.get(0);
// Has it got an entry?
if (it.hasNext()) {
// Return it's next.
return it.next();
} else {
// It's exhaused - remove it.
iterators.remove(it);
}
}
// We now deliver our element.
deliveredElement = true;
return value;
}
@Override
public void remove() {
throw new UnsupportedOperationException("remove() is not supported.");
}
}
}
public void test() {
TernaerTree<String> baum = new TernaerTree<String>(new TernaerTree<String>(null, null, null, "Hallo"), new TernaerTree<String>(null, null, null, "Welt"), new TernaerTree<String>(null, null, null, "?"), "!");
for (String s : baum) {
System.out.println(s);
}
}
我觉得您描述的要求有误,因为我希望元素在 right
分支之前出现,但这是可以修复的。
对于大学,我应该将接口迭代器实现为具有 3 Children 的树的内部 Class。 我对树的实现如下所示:
import java.util.*;
public class TernaerTree <E> {
private TernaerTree left;
private TernaerTree right;
private TernaerTree middle;
private E value;
public E getValue() {
return value;
}
public TernaerTree(TernaerTree left, TernaerTree middle, TernaerTree right, E value) {
this.left = left;
this.right = right;
this.middle = middle;
this.value = value;
}
public static void main(String [] args){
TernaerTree <String> baum = new TernaerTree<String>(new TernaerTree<String>(null,null,null,"Hallo"),new TernaerTree<String>(null,null,null,"Welt"),new TernaerTree<String>(null,null,null,"?"),"!");
}
public class WalkThroughIterator implements Iterator {
@Override
public boolean hasNext() {
}
@Override
public Object next() {
}
@Override
public void remove() {
throw new UnsupportedOperationException("remove() is not supported.");
}
}
}
现在我应该实现 WalkthroughIterator。它应该按以下顺序遍历树:左、中、右和节点本身。迭代器应该使用递归的子树迭代器。
在主要方法中,所有内容都应打印在屏幕上。
希望有人能帮助我。
谢谢, 托拜厄斯
我建议你让 TernaerTree 实现可迭代。那会让事情变得容易得多。您可以 return iterator() 中的 WalkThroughIterator 迭代器,您将为 iterable 实现该迭代器。这样就少了很多混乱。
那么你就可以把树的所有基本功能都作为TernaerTree的一部分。
最简单的方法(如果你不太关心复杂性/性能),你可以添加一个构造函数并按照你想要的递归顺序构建节点的线性 AST(例如,列表)。
public class WalkThroughIterator implements Iterator {
private List<E> values = new ArrayList<E>();
private int currentElement = 0;
public WalkThroughIterator(TernaerTree<E> tree) {
buildList(tree);
}
private void buildList(TernaerTree<E> node) {
if (node == null)
return;
buildList(node.left); //probably be best to add a getLeft() method etc
buildList(node.middle);
buildList(node.right);
values.add(node.getValue());
}
@Override
public boolean hasNext() {
return (currentElement < values.size());
}
@Override
public Object next() {
return values.get(currentElement++);
}
@Override
public void remove() {
throw new UnsupportedOperationException("remove() is not supported.");
}
}
然后只需将 getIterator
方法添加到您的树对象中即可:
public WalkThroughIterator getIterator() {
return new WalkThroughIterator(this);
}
或者简单地用根实例化一个新的 WalkThroughIterator
对象。
(顺便说一句,请注意,如果您让对象实现 Iterable
然后按照上面的建议实现,您可以使用 for-each 循环遍历树。)
这似乎可行 - 它使用 iterator
的列表来跟踪内部树。一旦所有这些都耗尽,它就会发出元素。
public class TernaerTree<E> implements Iterable<E> {
private TernaerTree left;
private TernaerTree middle;
private TernaerTree right;
private E value;
public E getValue() {
return value;
}
public TernaerTree(TernaerTree left, TernaerTree middle, TernaerTree right, E value) {
this.left = left;
this.middle = middle;
this.right = right;
this.value = value;
}
@Override
public Iterator<E> iterator() {
return new WalkThroughIterator();
}
public class WalkThroughIterator implements Iterator<E> {
// All the iterators of all of the sub-trees that weren't null.
List<Iterator<E>> iterators = new LinkedList<>();
// Have we delivered the element?
private boolean deliveredElement = false;
public WalkThroughIterator() {
// Is there a 'left' tree?
if (left != null) {
iterators.add(left.iterator());
}
// a middle
if (middle != null) {
iterators.add(middle.iterator());
}
// a right
if (right != null) {
iterators.add(right.iterator());
}
}
@Override
public boolean hasNext() {
// we've finished if we've delivered the element.
return !deliveredElement;
}
@Override
public E next() {
// First consume the iterators.
while (iterators.size() > 0) {
// Grab the first one.
Iterator<E> it = iterators.get(0);
// Has it got an entry?
if (it.hasNext()) {
// Return it's next.
return it.next();
} else {
// It's exhaused - remove it.
iterators.remove(it);
}
}
// We now deliver our element.
deliveredElement = true;
return value;
}
@Override
public void remove() {
throw new UnsupportedOperationException("remove() is not supported.");
}
}
}
public void test() {
TernaerTree<String> baum = new TernaerTree<String>(new TernaerTree<String>(null, null, null, "Hallo"), new TernaerTree<String>(null, null, null, "Welt"), new TernaerTree<String>(null, null, null, "?"), "!");
for (String s : baum) {
System.out.println(s);
}
}
我觉得您描述的要求有误,因为我希望元素在 right
分支之前出现,但这是可以修复的。