我有(Parent1 - > Child1),(Parent2 - > Child2),....,(ParentN - > ChildN)元组描述的有向无环图(树)。是否有任何算法可以从这些信息中重建树(图)?
一个更好的例子:
Root
Parent1
Node1
Child1
Child2
Parent2
Node1
Child1
Child2
作为输入我只有:
Root -> Parent1
Node1 -> Child1
Root -> Parent2
Parent1 -> Node1
Parent2 -> Node1
Node1 -> Child2
没有特别的顺序。
只有这些元组,我们可以在以下结构中重建树:
Node(name:String,children:List)?
答案 0 :(得分:2)
我不清楚你是否在寻找指针数据结构。您正在寻找的是,最终您应该能够列出节点的所有子节点。如果这是要求,您可以做的是创建一个哈希表(根据您的示例,从字符串到字符串)。然后在您的文件中,readline循环将父级设置为哈希表中的键,将字符串向量设置为相应的值。将孩子推到这个载体上。在C ++中,它将如下所示
#include <hash_map>
#include <vector>
#include <string>
using namespace std;
hash_map<string, vector<string>* > graph;
string parent, child;
然后在文件readline循环中
cin >> parent >> child >> child;
if ( graph[parent] == graph.end() ) {
graph[parent] = new vector<string>();
}
graph[parent]->push_back(child);
请记住在完成后删除矢量,或使用auto_ptr。
在伪代码中:
for every tuple:
create HashTable entry with key = tuple.parent
HashTable[tuple.parent].addToList(tuple.child)
答案 1 :(得分:1)
从根开始执行深度优先遍历,允许多次访问节点(当然,图形必须是非循环的才能终止)。对于您访问的每个图节点,您创建一个相应的树节点,并将其连接到其父图节点的相应树节点(编辑:实际上,图节点可以对应多个树节点,你对最后一个感兴趣)。
例如,假设你的根是A
:
A
/ \
/ \
B C
\ /
\ /
D
您访问A
,创建tA
。遍历转到B,您创建tB
,将其连接到tA
。然后你访问'D',创建tD
,将其连接到tB
,然后你回溯并访问'C',创建tC
并将其连接到tA
,这样你得到这棵树:
tA
/ \
/ \
tB tC
| |
| |
tD tD'
请注意,与图形相比,通过这种转换可能会获得指数级更大的树。