【问题标题】:Binary Search Tree Iterator - In/Pre/Post Order二叉搜索树迭代器 - 在/前/后顺序
【发布时间】:2017-06-21 07:27:33
【问题描述】:

我有一个类BinarySearchTree,它有两个数据元素Node rootint sizeNode 类有四个数据元素Node left, right, upint data

我想创建一个迭代器类,它的构造函数接受它将使用的遍历类型。只有在调用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()
    {
        ...
    }
}

【问题讨论】:

    标签: java data-structures tree


    【解决方案1】:

    您的问题听起来像是策略模式的用例。您的迭代器的构造函数应该获取实际的 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
    }
    

    【讨论】:

    • 这是我的意图,但我使用int 将问题简化为核心问题,即将进入迭代器的数据元素/算法
    【解决方案2】:

    最好的选择是引入工厂模式并将您的实现拆分为自己的Iterators。

    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> {
        //...
      }
    }
    

    【讨论】:

    • 我宁愿不拆分实现。相反,我宁愿拥有涵盖所有情况需求的实例变量。这是出于问题范围之外的原因。
    • 您在问MyIterator 中应该包含哪些数据元素,这样才不会变得混乱?。如果您不分心,恕我直言,这已经是一团糟了。
    【解决方案3】:

    Morris 中序树遍历及其变体是我正在寻找的结构/算法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 2015-01-18
      • 2020-12-12
      • 2017-05-09
      • 2011-06-02
      相关资源
      最近更新 更多