algorithm - 如何用它的 BFS 和 DFS 遍历构造一棵树

标签 algorithm graph depth-first-search breadth-first-search tree-traversal

我有树的BFSDFS 遍历。我怎样才能从这些遍历中重建树?

例如:

BFS Traversal : 4 3 5 1 2 8 7 6

DFS Traversal : 4 3 1 7 2 6 5 8

那么这棵树会像下面这样:

       4
      / \
     3   5    
    / \   \    
   2   1   8
   |   |         
   6   7      

最佳答案

这只有在 BFS 和 DFS 使用完全相同的顺序遍历 child 时才有可能:

规则 1:

BFS Traversal : 4 3 5 1 2 8 7 6
                | | |
                | | |-------|
                | |         |
DFS Traversal : 4|3 1 7 2 6|5 8

正如这个例子所示,我们可以很容易地知道 (3 , 1 , 7 , 2 , 6) 属于以 3 为根的子树。由于 1 也是该子树的一部分,我们可以得出 3 和 5 是 4 的唯一子节点。

规则 2:

BFS Traversal : 4 3 5 1 2 8 7 6
                | |   |
                | | |-|
                | | |        
DFS Traversal : 4 3 1 7 2 6 5 8

这样,我们可以证明 3 和 5 是 4 的 child 。

这也可以仅使用 BFS 和 DFS 的子集来完成,这些子集包含属于同一子树的节点(此示例是在规则 1 的演示中找到的子树):

使用规则 1:

BFS Traversal: 1 2 7 6
               | |
               | |-|
               |   |
DFS Traversal: 1|7|2 6

这表明 7 是 1 的唯一 child 。

使用规则 2:

BFS Traversal: 1 2 7 6
               |   |
               | |-|
               | |  
DFS Traversal: 1 7 2 6

因此 1 和 2 是同一父项(即 3)的子项。

翻译成伪代码看起来像这样:

addchild(int parent, int child) := add the child to the specified parent node

void process(int[] bfs , int[] dfs)
    int root = bfs[0]

    //find all peers (nodes with the same level and parent in the tree) using Rule 2
    int at = bfs.find(dfs[2])
    int peers[at - 1]
    for int i in [1 , at[
        peers[i - 1] = bfs[i]
        addchild(root , bfs[i])

    //for each of the childtree of the tree find it's children using Rule 1
    for int i in [0 , length(peers)[
        //all nodes that are either peers[i] or a child of peers[i]
        int[] children_dfs = dfs.subset(dfs.find(peers[i]) , (i < length(peers) - 1 ? dfs.find(peers[i + 1]) : length(dfs)) - 1)
        //a subset of bfs containing peers[i] and it's children in the order they have in bfs
        int[] children_bfs = bfs.allMatchingInOrder(children_dfs)

        //generate the subtree
        process(children_bfs , children_dfs)

关于algorithm - 如何用它的 BFS 和 DFS 遍历构造一棵树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32766824/

相关文章:

php - 试图在 PHP 中创建类似于近似子集和表的算法

algorithm - A* 算法和启发式函数。在图上找到最佳路径。

java - 深度优先搜索 1 循环打印

java - 使用java进行DFS回溯

algorithm - 使用插入排序对 10^7 条记录进行排序所花费的时间

java - 测试长度为 n 的未排序整数列表是否表示集合 {1,...,n}

c++ - 哪个更快? "vector of structs"还是 "a number of vectors"?

java - 图遍历问题

java - 控制台条形图使用循环,不带图形JAVA

algorithm - 如何检查女王是否在皇后区受到攻击