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

#include <stdio.h>
#define MaxSize 100
#define INF 32767	//INF表示∞
#define	MAXV 100	//最大頂點個數
typedef int InfoType;

typedef struct 
{  	
	int no;						//頂點編號
	InfoType info;				//頂點其他信息
} VertexType;					//頂點類型
typedef struct  				//圖的定義
{  	
	int edges[MAXV][MAXV]; 		//鄰接矩陣
   	int n,e;   					//頂點數,弧數
	VertexType vexs[MAXV];		//存放頂點信息
} MGraph;						//圖的鄰接矩陣類型

typedef struct 
{	
	int u;			//邊的起始頂點
    int v;			//邊的終止頂點
    int w;			//邊的權值
} Edge;

void InsertSort(Edge E[],int n) //對E[0..n-1]按遞增有序進行直接插入排序
{
	int i,j;
	Edge temp;
	for (i=1;i<n;i++) 
	{
		temp=E[i];
		j=i-1;				//從右向左在有序區E[0..i-1]中找E[i]的插入位置
		while (j>=0 && temp.w<E[j].w) 
		{
			E[j+1]=E[j];	//將關鍵字大於E[i].w的記錄後移
			j--;
		}
		E[j+1]=temp;		//在j+1處插入E[i] 
	}
}
void Kruskal(MGraph g)
{
	int i,j,u1,v1,sn1,sn2,k;
	int vset[MAXV];
	Edge E[MaxSize];				//存放所有邊
	k=0;							//E數組的下標從0開始計
	for (i=0;i<g.n;i++)				//由g產生的邊集E
		for (j=0;j<g.n;j++)
			if (g.edges[i][j]!=0 && g.edges[i][j]!=INF)
			{
				E[k].u=i;E[k].v=j;E[k].w=g.edges[i][j];
				k++;
			}
	InsertSort(E,g.e);				//採用直接插入排序對E數組按權值遞增排序

	for (i=0;i<g.n;i++) 			//初始化輔助數組
		vset[i]=i;
	k=1;                 			//k表示當前構造生成樹的第幾條邊,初值爲1
	j=0;                 			//E中邊的下標,初值爲0
	while (k<g.n)       			//生成的邊數小於n時循環
	{	
		u1=E[j].u;v1=E[j].v;        //取一條邊的頭尾頂點
		sn1=vset[u1];
		sn2=vset[v1]; 				//分別得到兩個頂點所屬的集合編號
		if (sn1!=sn2)     	  		//兩頂點屬於不同的集合,該邊是最小生成樹的一條邊
		{	
			printf("  (%d,%d):%d\n",u1,v1,E[j].w);
			k++;                    //生成邊數增1
			for (i=0;i<g.n;i++)     //兩個集合統一編號
				if (vset[i]==sn2)  	//集合編號爲sn2的改爲sn1
				    vset[i]=sn1;
		}
		j++;   						//掃描下一條邊
	}
}
void main()
{
	int i,j;
	MGraph g;
	g.n=6;g.e=20;
	int a[6][MAXV]={
		{0,6,1,5,INF,INF},
		{6,0,5,INF,3,INF},
		{1,5,0,5,6,4},
		{5,INF,5,0,INF,2},
		{INF,3,6,INF,0,6},
		{INF,INF,4,2,6,0}};
	for (i=0;i<g.n;i++)		//建立圖9.13(a)所示的圖的鄰接矩陣
		for (j=0;j<g.n;j++)
			g.edges[i][j]=a[i][j];
	printf("最小生成樹構成:\n");
	Kruskal(g);
	printf("\n");
}

 

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