最小生成樹

2021-09-06 21:19:36 字數 3406 閱讀 5808

/*1.乙個有n個頂點的連通圖的生成樹是原圖的極小連通圖,它包括原圖中的全部n個頂點,而且具有保持圖連通的最小的邊。

顯然有例如以下推論:

a.若刪除生成樹中的一條邊,就會使該生成樹因變成非連通圖而不再滿足生成樹的定義;

b.若在生成樹中新增一條邊,就會使該生成樹因存在迴路而不再滿足生成樹的定義。

c.乙個連通圖的生成樹可能有很多,使用不同尋找方法能夠得到不同的生成樹。

2.對於有n個頂點的無向圖,不管它的生成樹的形狀怎樣,一定有n個頂點,有且僅僅有n-1條邊

3.假設無向連通圖是乙個帶權圖,那麼它的全部生成樹中必有一棵邊的權值總和最小的生成樹,

我們稱這棵生成樹為最小代價生成樹,簡稱為最小生成樹。

4.構造有n個頂點的無向連通帶權圖的最小生成樹必須滿足下面三個要求:

a.構造的最小生成樹必須包含n個頂點;

b.構造的最小生成樹中有且僅僅有n-1條邊

c.構造的最小生成樹中部存在迴路

5.構造最小生成樹的典型方法有2種:一種稱作普里姆(prim)演算法,一種稱作克魯斯卡爾(kruskal)演算法

6.普里姆演算法思想:

如果g=(v,e)為乙個帶權圖,當中v為帶權圖中頂點的集合,e為帶權圖中邊的權值機會。

設定兩個新的集合u和t,當中u用於存放帶權圖g的最小生成樹的頂點的機會,t用於存放帶權圖g的最小生成樹

的權值的集合。

普里姆演算法的思想是:令集合u的初值為u=,即如果構造最小生成樹時從頂點u0開始,集合t的初值為t={}。

從全部頂點u屬於u和頂點v屬於v-u的帶權邊中,選出具有最小權值的邊(u,v),將頂點v增加集合u中,將邊(u,v)

增加集合t中。如此不斷反覆,當u=v時,最小生成樹構造完成。此時,集合u中存放著最小生成樹頂點的集合,集合t中存放著最小

生成樹邊的權值的集合。

7.克魯斯卡爾演算法:

設無向連通帶權圖g=(v,e),當中v為頂點集合,e為邊的集合。克魯斯卡爾演算法的思想是:

設帶權圖g的最小生成樹t由頂點集合和邊的集合構成,其初值為t=(v,{}),即初始時最小生成樹t僅僅有帶權圖g中的頂點集合組成,

各頂點之間沒有一條邊。這樣,最小生成樹t中的各個頂點各自構成乙個連通分量。然後,依照邊的權值遞增的順序考察帶權圖g中

的邊集合e中的各條邊,若被考察的邊的兩個頂點屬於t的2個不同的連通分量,則將此邊增加到最小生成樹t中,同一時候把兩個連通分量連線

為乙個連通分量;若被考察的邊的兩個頂點屬於t的同乙個連通分量,則將此邊捨去,當t中的連通分量個數為1時,t中的該連通分量即為帶權圖

g的一棵最小生成樹。

克魯斯卡爾演算法主要包含2個部分:首先是帶權圖g中e條邊的權值的排序,其次是推斷選取的邊的2個頂點是否屬於同乙個連通分量。

8.克魯斯卡爾演算法的時間複雜主要由排序方法決定,而克魯斯卡爾演算法的排序演算法僅僅與邊的個數有關,與圖頂點的個數無關。當使用時間複雜度為

o(elbe)的排序演算法時,克魯斯卡爾演算法得時間複雜度即為o(elbe)。因此,當帶權圖的頂點個數較多,而邊的個數較少時,使用克魯斯卡爾演算法

構造最小生成樹的時間效率較好。*/

#include#include#define maxsize 10        //定義元素的大小

typedef char datatype; //定義乙個型別

#define maxvertices 10 //定義頂點的最大值

#define maxweight 10000 //定義無窮大的詳細值

typedef char vert;

typedef structseqlist; //結構體的物件

typedef structadjmgraph;

typedef structrowcolweight;//邊資訊結構體

typedef structminspantree;

//初始化

void initiate(seqlist *l)

//求當前元素的個數

int getlength(seqlist l)

//插入資料元素

int insertdata(seqlist *l,int i,datatype x)else if(i<0||i>l->size)else

l->list[i]=x;

l->size++;

return 1;

}}//刪除資料

int deletedata(seqlist *l,int i,datatype *x)else if(i<0||i>l->size-1)else

l->size--;//資料元素減一

return 1; }}

//取出資料元素

int getdata(seqlist l,int i,datatype *x)else

}//初始化有n個頂點的順序表和鄰接矩陣

void initiateg(adjmgraph *g,int n)else

} }g->numofedges=0;//邊的條數置為0

initiate(&g->vertices);//順序表初始化

}//插入頂點

void insertvertex(adjmgraph *g,datatype vertex)

//插入邊

void insertedge(adjmgraph *g,int v1,int v2,int weight)

g->edge[v1][v2]=weight;

g->numofedges++;

}//刪除邊

void deleteedge(adjmgraph *g,int v1,int v2)

if(g->edge[v1][v2]==maxweight||v1==v2)

g->edge[v1][v2]=maxweight;

g->numofedges--;

}//取第乙個鄰接頂點

int getfirstvex(adjmgraph g,int v)

for(col=0;col0&&g.edge[v][col]g.vertices.size||v2<0||v2>=g.vertices.size)

for(col=v2+1;col0&&g.edge[v1][col]0)

} getdata(g.vertices,k,&x);//取弧頭頂點k

closevertex[i].vertex=x;//儲存弧頭頂點k的資料

closevertex[i].weight=mincost;//儲存對應的權值

lowcost[k]=-1;//標誌頂點k

//依據增加集合u的頂點k改動lowcost中的數值

for(j=1;j

結果輸出為:

最小生成樹 次小生成樹

一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...

最小生成樹

package 圖 最小生成樹是用最少的邊吧把所有的節點連線起來。於是和圖的深度優先搜素差不多。class stack public void push int key public int pop 檢視棧頂的元素 public int peek public boolean isempty cla...

最小生成樹

define max vertex num 20 最大頂點數 typedef int adjmatrix max vertex num max vertex num 鄰接矩陣型別 typedef char vertextype typedef struct mgraph struct dnodecl...