将 DAG 转换为二叉树

Converting a DAG to Binary Tree

我正在尝试将 DAG 转换为二叉树。考虑下图

我希望上面的树有以下输出。

由于A,B,C,E形成了一个菱形,要将其转化为一棵树,我需要将B和C移动成一条线。

我试过以下方法:

  1. 拓扑排序:输出为 A -> D -> B -> C -> E -> F 。
  2. 拓扑排序顺序:A -> [B,C,D] -> E -> F

拓扑路径为我们提供了一条直线路径。但是,我想尽可能保留序列,即 A -> D。但是,如果有菱形,我希望一个节点只有一个父节点并对这些父节点进行排序。

对于上述情况,有没有办法从 DAG 生成树?

算法伪代码

 Run a topological sort on the graph

 For every node B, in reverse order of the topological sort:
    If B has more than one parent:
        Order its parents A1, A2, ..., An in the order of the topological sort
        For every i in 1..n-1:
            Add an arc from Ai to A(i+1)
            Remove the arc from Ai to B

正确性证明

  • 算法总是终止,因为它是一个固定长度的循环;它的时间复杂度是 O(N^2) 其中 N 是节点数
  • 紧接在给定节点 B 上的步骤之后,B 不超过一个父节点
  • 如果给定节点C上的步骤已经执行,则在拓扑顺序中C之前的节点B上执行步骤只会向拓扑顺序中C之前的节点添加弧;因此,一旦执行了节点的步骤,它们就永远不会获得新的父节点。

证明算法终止,执行算法后每个节点至多有一个父节点。由于我们只从具有多个父节点的节点中删除父节点,我认为它也可以满足您的问题。