C# 如何为邻接表构造适合BFS的数据结构?

C# 如何为邻接表构造适合BFS的数据结构?,c#,data-structures,graph,adjacency-list,C#,Data Structures,Graph,Adjacency List,关于建立和搜索邻接树的面试问题,但我以前从未和他们合作过,所以我不确定从哪里开始 我有一个包含以下数据的文件: 2 13556 225 235 225 2212 226 2212 8888 2213 8888 144115 72629 141336 8889 146090 129948 167357 144115 160496 163089 144114 144116 ... 格式如下: <parent node> <child node> [ <child no

关于建立和搜索邻接树的面试问题,但我以前从未和他们合作过,所以我不确定从哪里开始

我有一个包含以下数据的文件:

2 13556 225 235
225 2212 226
2212 8888 2213
8888 144115 72629 141336 8889 146090 129948 167357
144115 160496 163089 144114 144116
...
格式如下:

<parent node> <child node> [ <child node> [ …] ]
[…]
每条边的长度为1

然后,我需要计算两个节点之间的最短路径(问题中指定了这两个节点)。然后,我需要用big-O表示法提供估计的复杂性

对于后者,我可能会胡编乱造,尽管直到现在我才听说过,而且维基百科在理解如何将搜索功能分解为big-O方面对我帮助不大,但我以后会担心这个问题(除非有人有一个好的链接可以共享)

我现在关心的是尝试对这些数据建模,然后搜索最短路径。就像我说的,我以前从未使用过这种结构,所以我有点不知所措,不知从哪里开始。我在邻接列表中发现了另一个问题,但它似乎不是我想要的,除非我完全没有抓住要点。在我看来,输入数据需要重新组织以满足该问题中使用的结构,而我正在从文件中读取数据,因此我认为我需要遍历每个节点和节点列表,以确定是否已输入父节点,这可能需要很长时间。我也不知道如何使用这种结构创建bfs搜索


有很多关于搜索的例子,所以我可能会对这部分进行分类,但是在启动数据模型方面的任何帮助都适用于从数据文件加载并适用于bfs搜索(或者,如果有更好的搜索选项,请告诉我),这将非常有帮助。

您希望将此数据存储在
哈希表(字典)(链接)中,键为int(NodeID),值为
List
,其中这些是作为键的节点的可能目的地

您需要另一个
哈希表(ShortestPathLastStep),它将存储两个节点ID。这将表示到达给定节点的最短路径的最后一步。你需要这个来回放最短路径

要执行BFS(广度优先搜索),您将使用
队列
(bfsQueue)。将开始节点(在问题中给出)推到队列上。现在执行以下算法

-- currentNodeID = pop bfsQueue
---- children = Links[NodeID]
------ foreach (childNodeID in children)
--------- if (childNodeID == destinationNodeID)
----------- exit and playback shortest path
----------if (!ShortestPathLastStep.contains(childNodeID))
------------ ShortestPathLastStep.Add(childNodeID, currentNodeID);
----------bfsQueue.Push(childNodeID);
----------goto first line

此解决方案假定在任意两个节点之间移动是一个固定成本。这是BFS的理想选择,因为当您第一次到达目的地时,您将采用最短路径(如果链接长度可变,则不适用)。如果链接长度不是恒定的,则在决定覆盖ShortestPathLastStep值时必须添加更多逻辑,直到队列为空时才能退出,并且只有在从未访问过该节点的情况下才能将节点推到队列上(该节点在短路径列表中不存在)或者,您发现这种新的到达方式比上一种到达方式要短(现在您必须重新计算从该节点可以到达的节点的最短距离)。

您需要将这些数据存储在
哈希表
(字典)(链接),键为int(NodeID),值为
List
,其中,这些是来自作为密钥的节点的可能目的地

您需要另一个
哈希表(ShortestPathLastStep),它将存储两个节点ID。这将表示到达给定节点的最短路径的最后一步。你需要这个来回放最短路径

要执行BFS(广度优先搜索),您将使用
队列
(bfsQueue)。将开始节点(在问题中给出)推到队列上。现在执行以下算法

-- currentNodeID = pop bfsQueue
---- children = Links[NodeID]
------ foreach (childNodeID in children)
--------- if (childNodeID == destinationNodeID)
----------- exit and playback shortest path
----------if (!ShortestPathLastStep.contains(childNodeID))
------------ ShortestPathLastStep.Add(childNodeID, currentNodeID);
----------bfsQueue.Push(childNodeID);
----------goto first line

此解决方案假定在任意两个节点之间移动是一个固定成本。这是BFS的理想选择,因为当您第一次到达目的地时,您将采用最短路径(如果链接长度可变,则不适用)。如果链接长度不是恒定的,则在决定覆盖ShortestPathLastStep值时必须添加更多逻辑,直到队列为空时才能退出,并且只有在从未访问过该节点的情况下才能将节点推到队列上(该节点在短路径列表中不存在)或者您发现这种新的到达方式比最后一种到达方式短(现在您必须重新计算从该节点可以到达的节点的最短距离)。

该列表不是列表吗?但是,在构建该哈希表时,我需要遍历每个哈希表条目的每个列表,以查找是否已经获得对该节点的引用,然后将新的子节点列表添加到其中,以便创建树,不是吗?至于搜索它,如果我一直在构建最短的PathLastStep哈希表,并且在没有找到所需的结束节点的情况下到达路径的结尾,该怎么办?我必须使用它并从树中的/某处/重新开始(因为从头开始会得到相同的结果),对吗?^^^^^^^^^^^^^或者我根本就没有得到这个结果?@Jon第一个哈希表是“按id查找节点”表。由于节点中没有额外的数据,我只是将子节点列表作为值,而不是创建节点类。无论哪种方式,我都可能将孩子们存储为ID列表(如果他们有ID的话),而不是整个类。至于创建表,我仍然不清楚您的输入是如何构造的,所以很难说。@Jon BFS的思想是,您通过计算长度为1的所有路径,然后计算长度为2的所有路径,然后依次进行搜索。DFS将查找到目的地的完整路径,然后尝试查找较短的路径,直到用尽所有可能的路径。@Jon您可能会发现查看图表和最短距离、最低成本的算法很有帮助。是这样吗