數據結構之---C語言實現最小生成樹之prim(普里姆)算法





//最小生成樹之Prim算法
//楊鑫
#include <stdio.h>
#include <stdlib.h>
#define n 6
#define MaxNum 10000  /*定義一個最大整數*/

/*定義鄰接矩陣類型*/
typedef int adjmatrix[n + 1][n + 1];   /*0號單元沒用*/
typedef struct
{
	int fromvex, tovex;      			//生成樹的起點和終點        
	int weight;							//邊的權重
}Edge;
typedef Edge *EdgeNode;					//定義生成樹的別名
int arcnum;     /*邊的個數*/

/*建立圖的鄰接矩陣*/
void CreatMatrix(adjmatrix GA)
{
	int i, j, k, e;
	printf("=============================\n");
	printf("圖中有%d個頂點\n", n);
	for(i=1; i<=n; i++)
	{
		for(j=1; j<=n; j++)
		{
			if(i==j)
			{
				GA[i][j]=0;         /*對角線的值置為0*/
			}
			else
			{
				GA[i][j]=MaxNum;    /*其他位置的值置初始化為一個最大整數*/
			}
		}
	}
	printf("請輸入邊的個數:\n");
	scanf("%d", &arcnum);
	printf("請輸入邊的信息,依照起點,終點,權值的形式輸入:\n");
	for(k=1;k<=arcnum;k++)
	{
		scanf("%d,%d,%d",&i,&j,&e);  /*讀入邊的信息*/
		GA[i][j]=e;
		GA[j][i]=e;
	}
}

/*初始化圖的邊集數組*/
void InitEdge(EdgeNode GE,int m)
{
	int i;
	for(i=1;i<=m;i++)
	{
		GE[i].weight=0;
	}
}

/*依據圖的鄰接矩陣生成圖的邊集數組*/
void GetEdgeSet(adjmatrix GA,EdgeNode GE)
{
	int i, j, k = 1;
	for(i=1;i<=n;i++)
	{
		for(j=i+1;j<=n;j++)
		{
			if(GA[i][j] !=0 && GA[i][j] != MaxNum)
			{
				GE[k].fromvex = i;
				GE[k].tovex = j;
				GE[k].weight = GA[i][j];
				k++;
			}
		}
	}
}

/*按升序排列圖的邊集數組*/
void SortEdge(EdgeNode GE,int m)
{
	int i,j,k;
	Edge temp;
	for(i=1;i<m;i++)
	{
		k=i;
		for(j=i+1;j<=m;j++)
		{
			if(GE[k].weight > GE[j].weight)
			{
				k=j;
			}
		}
		if(k!=i)
		{
			temp = GE[i];
			GE[i]=GE[k];
			GE[k]=temp;
		}
	}
}

/*利用普里姆算法從初始點v出發求鄰接矩陣表示的圖的最小生成樹*/
void Prim(adjmatrix GA,EdgeNode T)
{
	int i,j,k,min,u,m,w;
	Edge temp;
	/*給T賦初值。相應為v1依次到其余各頂點的邊*/
	k=1;
	for(i=1;i<=n;i++)
	{
		if(i!=1)
		{
			T[k].fromvex=1;
			T[k].tovex=i;
			T[k].weight=GA[1][i];
			k++;
		}
	}
	/*進行n-1次循環,每次求出最小生成樹中的第k條邊*/
	for(k=1;k<n;k++)
	{
		min=MaxNum;
		m=k;
		for(j=k;j<n;j++)
		{
			if(T[j].weight<min)
			{
				min=T[j].weight;m=j;
			}
		}
		/*把最短邊對調到k-1下標位置*/
		temp=T[k];
		T[k]=T[m];
		T[m]=temp;
		/*把新增加最小生成樹T中的頂點序號賦給j*/
		j=T[k].tovex;
		/*改動有關邊,使T中到T外的每個頂點保持一條到眼下為止最短的邊*/
		for(i=k+1;i<n;i++)
		{
			u=T[i].tovex;
			w=GA[j][u];
			if(w<T[i].weight)
			{
				T[i].weight=w;T[i].fromvex=j;
			}
		}
	}
}

/*輸出邊集數組的每條邊*/
void OutEdge(EdgeNode GE,int e)
{
	int i;
	printf("依照起點,終點。權值的形式輸出的最小生成樹為:\n");
	for(i=1;i<=e;i++)
	{
		printf("%d,%d,%d\n",GE[i].fromvex,GE[i].tovex,GE[i].weight);
	}
	printf("=============================\n");
}

int main()
{
	adjmatrix GA;
	Edge GE[n*(n-1)/2], T[n];
	CreatMatrix(GA);
	InitEdge(GE,arcnum);
	GetEdgeSet(GA,GE);
	SortEdge(GE,arcnum);
	Prim(GA,T);
	printf("\n");
	OutEdge(T,n-1);
	return 0;
}


結果:



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM