我从this geeksforgeeks article研究克鲁斯卡的MST。给出的步骤是:
我真的不觉得有任何需要使用分离集。相反,用于检查周期,我们可以只存储顶点于访问数组,只要选择了边缘将其标记为真。通过程序循环,如果我们找到一个边缘,其两个顶点是访问数组中,我们忽略了边缘。
换句话说,而不是存储一个不相交集森林,我们不能只存储表示哪些顶点已被链接到另一边缘在一些先前步骤的比特的阵列?
您所描述的方法将不会在所有情况下正常工作。作为一个示例,考虑这个线图:
A - - B - - C - - D
让我们假设A-B具有重量1,C-d具有重量2和B - C的重量将会有什么Kruskal算法在这里做?首先,它需要添加在A - B,然后是C - d,然后乙 - C.
现在想象一下,您的实现会做什么。当我们添加A - B,你会标示出A和B作为被参观了已经。当我们再放入C - d,你会标示出C和d作为被参观了已经。但后来,当我们试图将B加入A - C,因为B和C被访问,你会决定不添加边缘,留下未连接的结果。
这里的问题是,建立一个MST时您可以添加边缘连接已经被挂在过去的其他节点的节点。添加边缘的标准是因此不太“有这些节点被之前链接?”多“是已经有这些节点之间的路径?”这就是不相交集森林用武之地。
这是伟大的,你戳,并督促常规实现并想办法加以改进。你会学到很多关于这些算法,如果你这样做!在这种情况下,它只是恰巧正是你提出完全不是那么回事,看到为什么它不工作的原因的现行办法是它是什么帮助棚灯。
我真的不觉得有任何需要使用分离集。相反,用于检查周期,我们可以只存储顶点于访问数组,只要选择了边缘将其标记为真。通过程序循环,如果我们找到一个边缘,其两个顶点是访问数组中,我们忽略了边缘。
是的,你当然可以这样做。在这个算法中使用分离集的点是性能。使用合适的分离集实现产量比使用列表可以做得更好渐近性能的。
你的困惑可能是从第2步,这是不正确的措辞派生。
它说:“检查是否形成与迄今形成的生成树一个周期。”,但什么到目前为止已经形成不是一个生成树。这是断开的生成树的森林,还有一些未访问的顶点。
当你发现在森林中连接两个不同的生成树边缘的算法失败。这些顶点将已经访问过,但边缘不构成一个循环。