最小生成樹的prim算法和Kruskal算法的區(qū)別?
一、最小生成樹的prim算法和Kruskal算法的區(qū)別
Kruskal算法(克魯斯卡算法)
Kruskal算法是一種貪心算法,我們將每個edge按照權重大小進行排序,每次從邊集中取出權重最小且兩個頂點都不在同一個集合的邊加入生成樹中!注意:如果這兩個頂點都在同一集合內,說明已經通過其他邊相連,因此如果將這個邊添加到生成樹中,那么就會形成環(huán)!這樣反復做,直到所有的節(jié)點都連接成功!
在這個算法中,最重要的一環(huán)就是判斷兩個節(jié)點在不在同一個集合內,很多人想,那你直接用一個set來保存不就好了?這是思路顯然不行,因為假設A和其他三個節(jié)點相連,同屬一個集合,而B和另外三個節(jié)點相連,同屬一個集合,那么我們將A和B取并集時,是將這兩組數據合并一起的,如果使用set,那么當數據量大時還需要遍歷,復雜度就會很高,因此使用并查集就會效率快很多了!
并查集詳解和STL中的自定義哈希
?mp.weixin.qq.com/s/gGCQ9uqlNQYbBHtw83xgOw
對所有節(jié)點遍歷建立并查集,按照邊的權重建立最小堆
取出最小堆堆頂數據,并判斷兩端節(jié)點是否在同一集合
如不在,則將這兩個節(jié)點添加到同一集合,接著將邊加入生成邊,如在,則不進行操作,為無效邊
重復上面的操作,直到所有的邊都檢查完
unordered_set
??? auto cmp = [](const Edge& a, const Edge& b){
??????? return a.weight > b.weight;??? // 最小堆
??? };
??? vector
??? for(auto ite: graph.nodes){
??????? list.push_back(ite.second);
??? }
??? UnionFindSet unionFind(list);?? // 建立并查集
??? priority_queue
??? for(auto edge: graph.edges){
??????? smallQueue.push(*edge);
??? }
??? // 構造選中的輸出邊集
??? unordered_set
??? while(!smallQueue.empty()){
??????? Edge edge = smallQueue.較好();
??????? smallQueue.pop();
??????? if(!unionFind.isSameSet(edge.from, edge.to)){?
// 判斷是否為一個環(huán),如果一個邊的兩端節(jié)點為一個集合,那么必為一個閉合環(huán)
??????????? result.insert(edge);
??????????? unionFind.Union(edge.from, edge.to);
??????? }
??? }
??? return result;
}
Prim算法(普里姆算法)
Prim算法是另一種貪心算法,和Kuskral算法的貪心策略不同,Kuskral算法主要對邊進行操作,而Prim算法則是對節(jié)點進行操作,每次遍歷添加一個點,這時候我們就不需要使用并查集了。具體步驟為:
建立邊set用來存放結果,建立節(jié)點set用來存放節(jié)點同時用于標記是否被訪問過,建立邊的最小堆
開始遍歷所有節(jié)點,如果沒有訪問,則添加到節(jié)點set,然后將其相連的邊入堆。
從堆中取最小的邊,然后判斷to節(jié)點是否被訪問過,如果沒有,將這個邊加入生成樹(我們想要的邊),并標記該節(jié)點訪問。
然后將to節(jié)點所相連的邊添加到最小堆中,不然這個網絡就不會向外擴展了(這個步驟是必須的)。
循環(huán)上面的操作,直到所有的節(jié)點遍歷完。
注意:對于單連通,從一個節(jié)點出發(fā)就可以直接找到完整的最小生成樹,因此最外的for循環(huán)也可以為一個順序結構,但多連通,就需要從不同的節(jié)點出發(fā)了!!!
unordered_set
??? // 裝邊的最小堆
??? auto cmp = [](const Edge& e1, const Edge& e2){
??????? return e1.weight > e2.weight;
??? };
??? priority_queue
??? // 判斷節(jié)點是否訪問過
??? unordered_set
??? unordered_set
??? for(auto ite: graph.nodes){
??????? if(node_set.find(*ite.second) == node_set.end()){
??????????? // 如果沒有訪問,將其標記為訪問過,并把它對應的邊放入最小堆
??????????? node_set.insert(*ite.second);
??????????? for(Edge* edge: ite.second->edges){
??????????????? smallQueue.push(*edge);
??????????? }
??????????? // 在當前這個圖中尋找最小生成樹
??????? ????while(!smallQueue.empty()){
??????????????? // 從堆中取出一個最小權重邊,并取出對應節(jié)點
??????????????? Edge help_edge = smallQueue.較好();
??????????????? smallQueue.pop();
??????????????? Node edge_to = *(help_edge.to);
??????????????? // 然后判斷這個節(jié)點是否被訪問過,如果沒有則將這個邊加入邊集
? ??????????????if(node_set.find(edge_to) == node_set.end()){
??????????????????? result.insert(help_edge);
??????????????????? node_set.insert(edge_to);?? // 標記edge_to也已經訪問過了
??????????????????? for(Edge *newEdge: edge_to.edges){
??????????????????????? smallQueue.push(*newEdge);
??????????????????? }
??????????????? }
??????????? }
??????? }
??? }
??? return result;
}
那么對于這兩種算法,我們應該用哪種呢?記得某個人說過這句話,算法沒有優(yōu)劣,每個算法都有它的使用場景,在對的場合使用對的算法,這才是算法工程師應該做的事情!
由于Kruksal算法是對邊進行操作,先取出邊,然后判斷邊的兩個節(jié)點,這樣的話,如果一個圖結構非常的稠密,那么Kruksal算法就比較慢了,而Prim算法只是對節(jié)點進行遍歷,并使用set進行標記,因此會相對于Kruksal算法,在稠密圖方面好很多,因此Kruksal算法常用于稀疏圖,而Prim算法常用于稠密圖!
延伸閱讀:
二、什么是最小生成樹
在給定一張無向圖,如果在它的子圖中,任意兩個頂點都是互相連通,并且是一個樹結構,那么這棵樹叫做生成樹。當連接頂點之間的圖有權重時,權重之和最小的樹結構為最小生成樹!
在實際中,這種算法的應用非常廣泛,比如我們需要在n個城市鋪設電纜,則需要n-1條通信線路,那么我們如何鋪設可以使得電纜最短呢?最小生成樹就是為了解決這個問題而誕生的!

猜你喜歡LIKE
相關推薦HOT
更多>>
什么是 FTP,優(yōu)缺點是什么?
FTP 代表什么?FTP 是?File Transfer Protocol(文件傳輸協議)的縮寫。下面,我們來分解下這個詞。本質上來說,“協議”(或者說,互聯網協議...詳情>>
2023-10-15 23:19:27
什么是移動云計算?
一、什么是移動云計算移動云計算(MCC)是使用云技術交付移動應用程序的方法。如今,復雜的移動應用程可執(zhí)行諸如身份驗證、位置感知功能以及為...詳情>>
2023-10-15 20:38:55
kNN里面的兩種優(yōu)化的數據結構:kd-tree和ball-tree,在算法實現原理上有什么區(qū)別?
一、kd-tree和ball-tree在算法實現原理上的區(qū)別KD樹是對依次對K維坐標軸,以中值切分構造的樹,每一個節(jié)點是一個超矩形,在維數小于20時效率較高...詳情>>
2023-10-15 17:34:35
存儲服務器與普通服務器有什么區(qū)別?
一、存儲服務器與普通服務器的區(qū)別存儲服務器和普通服務器有以下區(qū)別:1、存儲能力不同存儲服務器的主要功能是存儲和管理數據,因此其存儲能力...詳情>>
2023-10-15 15:35:37熱門推薦
制作大型軟件一般選用什么類型的數據庫以保護數據安全?
沸什么是 FTP,優(yōu)缺點是什么?
熱怎么樣用django將后臺數據庫表里面的內容以Excel表格的形式顯示到網頁中?
熱access數據庫中,查詢設計怎么規(guī)定小數位數?
新數據庫Union連接兩張表之前,怎么判斷要連接的另一張表是否存在?
什么是工業(yè) IoT?
面部識別是否安全?
聊天機器人是什么?
什么是移動云計算?
機器學習可用在哪些領域??
什么是數字化轉型戰(zhàn)略?
數據集市有哪些類型??
RESTful API 客戶端請求包含哪些內容?
云文件存儲有哪些用途?
技術干貨







快速通道 更多>>
-
課程介紹
點擊獲取大綱 -
就業(yè)前景
查看就業(yè)薪資 -
學習費用
了解課程價格 -
優(yōu)惠活動
領取優(yōu)惠券 -
學習資源
領3000G教程 -
師資團隊
了解師資團隊 -
實戰(zhàn)項目
獲取項目源碼 -
開班地區(qū)
查看來校路線