設圖g(v,e)
連通,則
生成樹:包含圖g(v,e)
中的所有節點,及|v|-1
條邊的連通圖,乙個圖的生成樹可以有多顆
最小生成樹:最小權重生成樹,在生成樹的概念上加乙個限制條件,即生成樹的所有邊的權值總和最小的樹,最小生成樹也可以有多顆
由於最小生成樹包含圖g的所有邊,所以我們需要做的只是尋找最小生成樹的邊集a
設:邊集a是圖g的任意一顆最小生成樹的邊的子集,初始時a為空當a不等於g的某個最小生成樹的所有邊集m時迴圈以下步驟 找到一條屬於m但不屬於a的邊,加入到a中
現在問題我們如何去尋找那條只屬於m但不屬於a的邊
邊v的尋找方法
當a為空時,圖g(v,a)是乙個有|v|個樹的森林,當a中有n條邊時,n
kruskal
和prim
演算法是最小生成樹常用的兩種演算法,這兩種演算法都是對上述通用方法的細化,不同之處就是對邊v的尋找方法上有所差異,kruskal
演算法又叫做(邊擴充套件)演算法,適用於邊稀疏的圖,prim
演算法叫做(節點擴充套件演算法),適用於邊稠密的圖
makeset
操作建立乙個包含|v|顆樹的集合,每顆樹只包含乙個節點,我們要為每個節點x新增兩個屬性
var makeset = (function()
})();
找到並返回x節點所在的那顆樹的根節點,用於判斷兩個節點是否在同一顆樹中,即是否相交
function find(x)
union
函式旨在合併兩個節點,應該將這裡的合併和在圖g中的連通區分開,我們通過不斷呼叫union
來改變makeset
集合中元素的連通性,被合併的兩個節點會變成一顆數,當然讀者也可以實現自己的union
,隨意實現都行,只有呼叫union
操作之後改變了makeset
,中圖的連通性,是的u
,v
節點處於同一顆樹就行,本文的union
方法採用的思想是按秩合併(秩 rank)、路徑壓縮
,通過這種方式建立的樹的節點分布,會比較均勻,平衡性較高,也就導致操作效率很高
function union(u, v)
}
kruskal演算法旨在尋找最小生成數中包含哪些邊,在後面的完整**中,該函式的實現會有所不同,這裡著重體會原理
function kruskal(g, w)
//對g.e按照邊的權中從小到大排序
for(let e of g.e)
//由於邊已經按照從小到大的順序有序,所以這裡只需要尋找不相交的邊(邊所在的樹不相交),
for(let e of g.e)
}return a;
}
這裡的資料結構及如何建圖參照 bfs,dfs 演算法原理及js實現,這裡不做詳細說明
//頂點資料結構
function vertex()
//資料結構 鄰接鍊錶-邊
function edge()
//資料結構 圖-g
function graph()
graph.prototype =
//初始化 字典
for (let i in this.v)
},//建立圖中 邊 的關係
initedge: (function()
return function(edges)
}}()),
storageedge: function(edges)
}var vertexs = [, , , , ];
var edges = [,,
,,,,
,,,,
,,,]var g = graph();
g.initvertex(vertexs);
g.storageedge(edges);
執行這部分**,生成了用於kruskal演算法輸入的圖
測試的演算法的輸入圖為上圖,紅色的邊為最終最小生成樹包含的邊,出現順序依次為ac,de,ab,bd
,這裡的輸入圖為無向圖
//快速排序 陣列a由物件組成 key為排序的參照指標 quicksort(0,a.length-1,a,'key')
function quicksort(left, right, a, key)
}a[left] = a[i];
a[i] = benchmark;
quicksort(left, i - 1, a, key);
quicksort(i + 1, right, a, key);
}var makeset = (function()
})();
//體會兩個 find 方法的不同
// function find(x)
function find(x)
function union(u, v)
}function kruskal(g)
//對g.e按照邊的權中從小到大排序
for(let e of g.e)
for(let e of g.e)
}return a;
}function vertex()
//資料結構 鄰接鍊錶-邊
function edge()
//資料結構 圖-g
function graph()
graph.prototype =
//初始化 字典
for (let i in this.v)
},//建立圖中 邊 的關係
initedge: (function()
return function(edges)
}}()),
storageedge: function(edges)
}//測試資料
var vertexs = [, , , , ];
var edges = [,,
,,,,
,,,,
,,,]var g = graph();
g.initvertex(vertexs);
g.storageedge(edges);
var a = kruskal(g);
console.log(a);
Kruskal最小生成樹及應用
生成樹 已知連通圖g,圖上有n個頂點。生成樹是指圖g的乙個極小 邊最少 連通子圖,生成樹上有n個頂點,n 1條邊,且任意兩點之間都是聯通的。最小生成樹 已知帶權連通圖g,圖中有n個頂點,每條邊都有權值。要從圖中抽出一棵生成樹,使得樹上所有邊權之和最小,這棵樹就叫做最小生成樹 mininum span...
kruskal 最小生成樹
include include 產生隨機數組用 include 同上 include using namespace std 1 帶權邊的類myarc class myarc bool operator const myarc arc myarc myarc int beginvex,int end...
最小生成樹Kruskal
最小生成樹有兩個特點,乙個是保證了所有邊的和是最小值,另乙個是保證了所有邊中的最大值最小。struct edge bool friend operator edge a,edge b 構邊 vectoredge int id max int mini void initial void input ...