最小生成樹

最小生成樹:我們把構造連通網的最小代價生成樹稱爲最小生成樹。


普里姆算法:

假設N = {V, E}是連通網,TE是N上最小生成樹中邊的集合。算法從U={u0}(u0∈V),TE={}開始。重複執行下述操作:在所有u∈U,v∈V-U的邊(u, v)∈E中找代價最小的邊(u0, v0)併入集合TE,同時v0併入U,直至U=V爲止。此時TE中必有n-1條邊,則T={V, TE}爲N的最小生成樹。此算法的時間複雜度是O(NxN)。

void MiniSpanTree_Prim(MGraph G)
{
	int min, i, j, k;
	int adjvex[MAXVEX];
	int lowcost[MAXVEX];

	lowcost[0] = 0;
	adjvex[0] = 0;

	for (i = 1; i < G.numVertexes; i++)
	{
		lowcost[i] = G.arc[0][i];
		adjvex[i] = 0;
	}
	for (i = 1; i < G.numVertexes; i++)
	{
		min = INFINITY;
		j = 1;k = 0;
		while (j < G.numVertexes)
		{
			if (lowcost[j] != 0 && lowcost[j] < min)
			{
				min = lowcost[j];
				k = j;
			}   
			j++;
		}
		printf("(%d, %d) ", adjvex[k], k);
		lowcost[k] = 0;
		for (j = 1; j < G.numVertexes; j++)
		{
			if (lowcost[j] != 0 && G.arc[k][j] < lowcost[j])
			{
				lowcost[j] = G.arc[k][j] ;
				adjvex[j] = k;
			}
		}
	}
}



克魯斯卡爾算法:

假設N={V, E}是連通網,則令最小生成樹的初始狀態爲只有n個頂點而無邊的非連通圖T={V, {}},圖中每個頂點自成一個連通分量。在E中選擇代價最小的邊,若該邊依附的頂點落在T中不同的連通分量上,則將此邊加入到T中,否則捨去該邊而選擇下一條代價最小的邊。依次類推,直至T中所以頂點都在同一連通分量爲止。此算法的時間複雜度是O(eloge)。

typedef struct 
{
	int begin;
	int end;
	int weight;
} Edge;

int Find(int *parent, int f)
{
	while (parent[f] > 0)
		f = parent[f];
	return f;
}

void MiniSpanTree_Kruskal(MGraph G)
{
	int i, n, m;
	Edge edges[MAXEDGE];
	int *parent[MAXVEX];

	//此次省略將鄰接矩陣G轉化爲邊集數組edges並按權由小到大排序的代碼
	
	for (i = 0; i < G.numVertexes; i++)
		parent[i] = 0;
	for (i = 0; i < G.numEdges; i++)
	{
		n = Find(parent, edges[i].begin);
		m = Find(parent, edges[i].end);
		if (n != m)
		{
			parent[n] = m;
			printf ("(%d, %d) %d ", edges[i].begin, edges[i].end, edges[i].weight);
			
		}
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章