树结构的通用遍历

时间:2017-12-19 20:35:08

标签: c++ algorithm generics tree traversal

我正在尝试编写我的树(好吧,它是二进制trie)遍历更通用,因为它现在的方式我有非常相似的代码重复。

我正在按字典顺序走树。 我认为可以通过通用树遍历抽象的函数示例是(伪代码):

items(node*, key, list&) {
    if(node->value)
        list.push({node->value, key})
    if(node->left)
        items(node->value, key + "0")
    if(node->right)
        items(node->value, key + "1")
}

draw(node*, id, ostream&) {
    drawNode(node, id)
    if (node->left)
        drawLine(node, node->left, "0", ostream&)
        draw(node->left, ++id, ostream&)
    if (node->right)
        drawLine(node, node->right, "1", ostream&)
        draw(node->right, ++id, ostream&)

我不是要求正常运行的代码,只是向正确的方向发展。应该使用模板作为参数吗?那些更复杂的情况呢,其中遍历不仅仅受单个左/右节点存在的限制(两个trie的合并似乎太像是这个抽象的候选者)。

2 个答案:

答案 0 :(得分:1)

遍历的通用抽象是一种合适的迭代器形式。一旦遍历成为一个线性的位置序列,你就可以使用一个传统的迭代器来构造它,很可能是对BidirectionalIterator进行建模。在概括遍历树(或更一般的图形)时,您可能会在不同方向上进行迭代操作。

答案 1 :(得分:0)

死灵张贴,但如果有人遇到这个问题,仍然值得。

泛型树遍历是功能编程理论家的研究,他们最终为haskell创建了几个可用的库。我将指向recursion-schemessyb(取消边界框)库。两者都随附描述所采用方法的论文。

Syb依赖于一种运行时反射形式,并使用了大量类型强制转换/强制转换,但是递归方案已移植到包括kotling和scala在内的多种语言中,因此它们与命令式语言兼容。

绝不是这些作品代表了树状数据结构的递归遍历可以做到的事情的巅峰之作,但是他们看到了一些用途,并且这些想法都经过了充分的测试。