最小生成樹原理及Kruskal演算法的js實現

2021-09-14 05:08:41 字數 3529 閱讀 7083

設圖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

kruskalprim演算法是最小生成樹常用的兩種演算法,這兩種演算法都是對上述通用方法的細化,不同之處就是對邊v的尋找方法上有所差異,kruskal演算法又叫做(邊擴充套件)演算法,適用於邊稀疏的圖,prim演算法叫做(節點擴充套件演算法),適用於邊稠密的圖

makeset操作建立乙個包含|v|顆樹的集合,每顆樹只包含乙個節點,我們要為每個節點x新增兩個屬性

var makeset = (function()

})();

找到並返回x節點所在的那顆樹的根節點,用於判斷兩個節點是否在同一顆樹中,即是否相交

function find(x)
union函式旨在合併兩個節點,應該將這裡的合併和在圖g中的連通區分開,我們通過不斷呼叫union來改變makeset集合中元素的連通性,被合併的兩個節點會變成一顆數,當然讀者也可以實現自己的union,隨意實現都行,只有呼叫union操作之後改變了makeset,中圖的連通性,是的uv節點處於同一顆樹就行,本文的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 ...