我有一个班级BinarySearchTree
,其中有两个数据元素Node root
和int size
。 Node
类有四个数据元素Node left, right, up
和int data
。
我想创建一个Iterator类,其构造函数接受它将要使用的遍历类型。只有在调用next
时,它才会迭代下一个元素。
MyIterator
中应包含哪些数据元素,以免变得混乱?我想也许有Stack<Node>
,但感觉这是一个非常糟糕的解决方案。我能做些什么聪明才能涵盖所有三种可能的模式?如果没有迭代器内部的额外数据结构(队列/堆栈/映射),有没有办法做到这一点?
public class MyIterator
{
private BinarySearchTree tree;
private Node current;
private int mode;
public MyIterator(BinarySearchTree tree, int mode)
{
// mode = 1 -> IN ORDER TRAVERSAL
// mode = 2 -> PREORDER TRAVERSAL
// mode = 3 -> POSTORDER TRAVERSAL
this.tree = tree;
this.mode = mode;
}
public boolean hasNext()
{
...
}
public void next()
{
...
}
}
答案 0 :(得分:0)
您的问题听起来像是策略模式的用例。您的Iterator的构造函数应该将实际的 ModeStrategy 作为参数而不是普通的 int 。策略存储在类属性中。 ModeStrategy 可能是一个看起来像这样的界面:
public interface ModeStrategy {
boolean hasNext(BinarySearchTree tree, Node current);
void next(BinarySearchTree tree, Node current);
}
public class MyIterator {
private final ModeStrategy mode;
// other fields omitted
public MyIterator(BinarySearchTree tree, ModeStrategy mode) {
this.mode = mode;
}
// your methods delegate to mode
}
答案 1 :(得分:0)
最好的选择是引入工厂模式并将实现拆分为自己的Iterator
。
final class IteratorFactory {
enum Mode {
IN_ORDER, PRE_ORDER, POST_ORDER;
}
private IteratorFactory() {
}
public static <T> Iterator<T> get(Mode mode, BinarySearchTree<T> tree) {
Objects.requireNonNull(mode);
Objects.requireNonNull(tree);
switch(mode) {
case IN_ORDER: return new InOrderIterator<T>(tree);
case PRE_ORDER: return new PreOrderIterator<>(tree);
case POST_ORDER: return new PostOrderIterator<>(tree);
default: throw new AssertionError("Can't happen");
}
}
private static class InOrderIterator<T> implements Iterator<T> {
//...
}
private static class PreOrderIterator<T> implements Iterator<T> {
//...
}
private static class PostOrderIterator<T> implements Iterator<T> {
//...
}
}
答案 2 :(得分:0)
Morris Inorder Tree Traversal及其变体是我正在寻找的结构/算法。