簡體   English   中英

Kruskal 的算法能否以這種方式實現,而不是使用不相交集的森林?

[英]Could Kruskal’s algorithm be implemented in this way instead of using a disjoint-set forest?

我正在從這篇 geeksforgeeks 文章中學習 Kruskal 的 MST。 給出的步驟是:

  1. 按重量的非遞減順序對所有邊進行排序。

  2. 選擇最小的邊。 檢查它是否與到目前為止形成的生成樹形成一個循環。 如果未形成環,則包括此邊。 否則,丟棄它。

  3. 重復步驟(2),直到生成樹中有(V-1)條邊。

我真的覺得沒有必要使用不相交的集合。 為了檢查循環,我們可以將頂點存儲在訪問數組中,並在選擇邊時將它們標記為真。 循環遍歷程序,如果我們找到一條邊,其兩個頂點都在訪問數組中,我們將忽略該邊。

換句話說,不是存儲一個不相交集的森林,我們不能只存儲一個位數組來指示哪些頂點在之前的某個步驟中已鏈接到另一條邊?

我真的不需要使用不交集。 代替檢查周期,我們可以將頂點存儲在訪問數組中,並在選擇邊時將其標記為true。 如果我們找到一條兩條頂點都位於訪問數組中的邊,則在程序中循環,我們將忽略該邊。

是的,您當然可以做到。 在該算法中使用不交集的重點是性能 與使用List相比,使用合適的不相交集實現可產生更好的漸近性能。

您所描述的方法在所有情況下均無法正常工作。 例如,考慮以下折線圖:

A - - B - - C - - D

假設AB的權重為1,CD的權重為2,B-C的權重為3。Kruskal的算法在此做什么? 首先,它將添加A-B,然后添加C-D,然后添加B-C。

現在想象一下您的實現會做什么。 當我們添加A-B時,您會將A和B標記為已訪問。 然后,當我們添加C-D時,您將C和D標記為已訪問。 但是,當我們嘗試添加B-C時,由於同時訪問了B和C,因此您將決定不添加邊,從而留下未連接的結果。

這里的問題是,在建立MST時,您可能會添加鏈接過去已鏈接到其他節點的節點的邊。 因此,添加邊緣的標准是“這些節點之前已經鏈接過嗎?”較少,而更多的是“這些節點之間已經存在路徑了嗎?”,這就是不交集的森林出現的地方。

戳破和推動常規實現,並試圖找到改進方法的做法真是太好了。 如果您這樣做的話,您將學到很多有關這些算法的知識! 在這種情況下,恰好發生了您所提議的內容行不通的情況,而了解其為何行不通的情況有助於您弄清現有方法為何如此。

您的困惑可能來自第2步,其措詞不正確。

它說:“檢查它是否與迄今為止形成的生成樹一起形成一個循環。”,但到目前為止所形成的不是生成樹。 這是一個由不連貫的生成樹和一些未訪問的頂點組成的森林

在林中找到連接兩個不同生成樹的邊時,算法將失敗。 這些頂點將在以前訪問過,但是邊緣不會循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM