我有一个节点/顶点列表,以及连接这些节点的线/边列表。这些列表没有以任何方式排序或排序,但包含特定数据集的所有边和节点。
边是由笛卡尔坐标定义的线段,(x1,y1) 和 (x2,y2),每个节点位置也用坐标表示,形式为 (x,y)。所附图像描绘了一个典型的测试用例,清楚地显示了两棵树,根为 R1 和 R2,每个节点,包括叶节点(标记为 Lx,以及突出显示的橙色文本和蓝色圆圈)以相应的坐标显示。
class Node
{
Point coordinates; // x,y coordinates of node <int,int>
Node parentNode; // parent node of current node. ( may not be necessary as parentID may suffice to keep reference to parent node)
List<Node> children; // List of all child nodes of this node
List<Edge> edges; // list of all edges connected to this node
string Data; // relevant data of each node
long nodeID; // current nodes ID
long parentID; // ID of current node's parent node
}
每条边表示为:
class Edge
{
Point p1; // first end coordinates of line segment
Point p2; // coordinates of the other end of the segment
}
从所附图像中,很明显边缘 N1-N2 将表示为 p1= (0,0), p2=(20,20) 或 p1 =(20,20), p2 = (0,0)。顺序是随机的。
假设 1:节点 R1 和 R2 可以清楚地识别为根节点,因为它们上的节点类型。(带有红色外圈的同心圆)。假设 2:直接连接到节点的所有边的列表也是可用的,例如,节点 N8 将具有段:N8-L7,N8-R2,N8-N9,N8-N7。
我的问题是如何在 C# 中编写一个函数,它有两个输入,一个边列表和一个节点列表,并返回一个根节点,或者参考子节点的树的根节点,这也是相同的/与附图中所描绘的内容相符。
List<Node> getRootNodes(List<Node> nodes, List<Edge> edges)
{
// implementation here
List<Node> roots = new List<Node>();
//more logic
//
//
return roots; //returned list may have more than one root node!
}
我已经能够列出每个节点的边缘,但无法找出构造树的方法。我已经阅读了关于Kruskal's Algorithm 的内容,但我不确定我是否可以使其适应这个问题。我不确定它是否会保留图中所示的顺序。
所有代码都在 C# 中,但任何 C 风格的语言解决方案都可以。
注意:我在这个网站上看到的答案假设树节点在父节点和子节点方面的顺序是已知的。我可以说两个节点由一条边连接,但无法确定哪个节点是父节点,哪个是子节点。
谢谢,
格雷格 M