【问题标题】:How to create an iterator wrapper for DAG structure in Java?如何在 Java 中为 DAG 结构创建迭代器包装器?
【发布时间】:2010-11-15 13:26:23
【问题描述】:

我想要一个数据结构的迭代器。 现在我不知道数据结构是什么,也许它是一个 DAG(有向无环图),但也许它也可能是一个链表。 所以我想把它包装成一个迭代器,现在不要考虑特定的数据结构。

我知道如何使用类似递归的访问者访问 DAG, 但我想不出一个简单而干净的结构来实现迭代器方法next()hasNext()

在迭代器中,我创建了一个当前节点实例,并使用 for 循环遍历所有子节点,然后返回父节点。需要一个“已访问”标志。 所以我的DagElement 多了这些属性:

DagElement parent
boolean alreadyVisited

我认为这不是一个干净的解决方案。

有什么建议吗?

【问题讨论】:

  • 迭代器的实现自然完全取决于数据结构,也取决于你想要迭代的顺序。决定这两点并更新问题。无论如何,alreadyVisited 不应该是数据结构的成员,而是在迭代器中保留对访问节点的引用的 Set
  • 您好,感谢您的评论,已经在一个集合中访问过非常好\n。直到现在我知道:我的数据结构是一棵树,我正在“预购”访问(访问根,访问子)。但是事情可能会改变,我想留下一个明确的方法来改变它。所以,也许在将来,有人想拿我的代码,使用另一个数据结构(比如,一个链表)和另一个顺序(比如,从尾到头反转)并为他的 ListElement 实现 Element 和他的 ListIterator 实现迭代器编写代码,并且使用仅依赖于 Element 和 Iterator 接口的代码。我走错方向了吗?
  • 正如我所说,迭代器的实现完全取决于数据结构的实现。如果您可以创建一个可以迭代任何数据结构的通用迭代器,那么已经有人这样做了。

标签: java tree iterator visitor-pattern directed-acyclic-graphs


【解决方案1】:

将递归启发式转换为迭代启发式的快速而简单的方法是使用 (LIFO) 堆栈或 (LILO) 队列来保存“未采用的道路”——已找到但尚未采用的路径。在这种情况下,迭代器将有一个堆栈或队列实例变量。比如:

    class DagIterator<T>
    extends Iterator<T> {

        private Stack<DagNode<T>> nodes;

        private DagIterator(Dag<T> dag) {
            nodes.push(dag.getRootNode());
        }

        public boolean hasNext() {
            return ! nodes.isEmpty();      
        }

        public T next() {
            final DagNode node = nodes.pop();
            for (final DagNode child : node.getChildren()) {
                nodes.push(child);
            }
            return node.getValue();
        }

    }

您可以根据数据结构(LIFO 或 LILO)、孩子排队的顺序以及排队的时间来调整访问顺序。我不会感到惊讶的是,某些访问顺序可能需要立即(在构造函数中)以正确的顺序对整个节点集进行排队。

【讨论】:

    猜你喜欢
    • 2011-08-23
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-09
    • 2018-04-14
    • 1970-01-01
    相关资源
    最近更新 更多