利用克魯斯卡爾演算法求最小生成樹

2021-10-01 08:18:23 字數 1816 閱讀 4980

思路:最小生成樹即為無向連通圖g的乙個子圖如果是一顆包含g的所有頂點且權最小的樹則稱為最小生成樹。克魯斯卡爾演算法的基本思想是以邊為主導地位,始終選擇當前可用的(所選的邊不能構成迴路)最小權值邊。所以第一步是將所有邊按照權值從小到大的順序排序,接下來從小到大依次考察每一條邊。具體實現過程如下:

<1>設乙個有n個頂點的連通網路為g(v,e),最初先構造乙個只有n個頂點,沒有邊的非連通圖t=,圖中每個頂點自成一格連通分量。

<2>在e中選擇一條具有最小權植的邊時,若該邊的兩個頂點落在不同的連通分量上,則將此邊加入到t中;否則,即這條邊的兩個頂點落到同一連通分量上,則將此邊捨去(此後永不選用這條邊),重新選擇一條權植最小的邊。

<3>如此重複下去,直到所有頂點在同一連通分量上為止。

在上面的演算法思路中,最為複雜的部分是連通分量的查詢和合併,並查集這個資料結構可以方便快速的解決這個問題。基本的處理思想是:初始時把每個物件看作是乙個單元素集合;然後依次按順序讀入聯通邊,將連通邊中的兩個元素合併。在此過程中將重複使用乙個搜尋(find)運算,確定乙個集合在那個集合中。當讀入乙個連通邊(u,v)時,先判斷u和v是否在同乙個集合中,如果是則不用合併;如果不是,則用乙個合併運算把u、v所在集合合併,使得這兩個集合中的任意兩個元素都連通。因此並查集在處理時,主要用到搜尋和合併兩個運算。為了方便並查集的描述與實現,通常把先後加入到乙個集合中的元素表示成乙個樹結構,並用根結點的序號(在這裡根節點的序號就是陣列的下標值)來表示這個集合。因此定義乙個parent[n]的陣列,parent[i]中存放的就是結點i+1所在的樹中結點i+1的父親節點的序號。

#include

#include

#define maxvex 20

#define inf 32767

typedef

struct

adjmatrix;

//圖

typedef

struct

brim;

//邊

intlocatevex

(adjmatrix* g,

char v)

;void

create

(adjmatrix *g)

;int

find

(int

*parent,

int f)

;void

kruskal

(adjmatrix *g)

intmain()

intfind

(int

*parent,

int f)

void

create

(adjmatrix *g)

}for

(i =

0; i < g->vexnum; i++

)getchar()

;for

(i =

0; i < g->arcnum; i++)}

void

kruskal

(adjmatrix *g)}}

for(i =

0; i < k -

1; i++)}

}int parent[maxvex]=;

for(

int i =

0; i < g->arcnum; i++

)printf

("(%c,%c,%d,%d)"

, g->vex[brim[i]

.start]

, g->vex[brim[i]

.end]

, brim[i]

.weight, brim[i]

.isused);}

}

克魯斯卡爾求最小生成樹

處理何種問題 求解最小生成樹,適合點多邊少的無向圖。以證明,放心用 效能 時間複雜度為o e loge e為邊的個數。原理 貪心策略 實現步驟 1 設乙個有n個頂點的聯通網路為g v,e 最初先構造乙個只有n個頂點,沒有邊的非連通圖t 圖中的每乙個頂點自成乙個連通分量。2 在e中選擇一條具有最小權值...

最小生成樹 克魯斯卡爾演算法

c node.h檔案 儲存頂點資訊 class c node c node c node c node p node c node c node c node c node char p data node.h檔案,儲存邊資訊 include class link node link node li...

最小生成樹( 克魯斯卡爾演算法)

name author date 01 12 14 20 17 description 最小生成樹 克魯斯卡爾演算法 關於並查集的演算法,參見 一種簡單而有趣的資料結構 並查集 include include define maxn 1000 最大頂點數量 define max 20000 最大邊數...