数据结构之---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;
}

结果:

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-28 17:36:49

数据结构之---C语言实现最小生成树之prim(普里姆)算法的相关文章

数据结构例程——最小生成树的普里姆算法

本文是[数据结构基础系列(7):图]中第11课时[最小生成树的普里姆算法]的例程. (程序中graph.h是图存储结构的"算法库"中的头文件,详情请单击链接-) #include <stdio.h> #include <malloc.h> #include "graph.h" void Prim(MGraph g,int v) { int lowcost[MAXV]; //顶点i是否在U中 int min; int closest[MAXV]

数据结构(五)图---最小生成树(普里姆算法)

一:最小生成树 (一)定义 我们把构造连通网的最小代价生成树称为最小生成树 (二)什么是最小生成树? 1.是一棵树 1)无回路 2)N个顶点,一定有N-1条边 2.是生成树 1)包含全部顶点 2)N-1条边都在图中 3.边的权重和最小 (三)案例说明 在实际生活中,我们常常碰到类似这种一类问题:如果要在n个城市之间建立通信联络网, 则连通n个城市仅仅须要n-1条线路.这时.我们须要考虑这样一个问题.怎样在最节省经费前提 下建立这个通信网.换句话说,我们须要在这n个城市中找出一个包括全部城市的连通

数据结构之最小生成树(普里姆算法)

1)普里姆算法 可取图中任意一个顶点v作为生成树的根,之后若要往生成树上添加顶点w,则在顶点v和顶点w之间必定存在一条边,并且 该边的权值在所有连通顶点v和w之间的边中取值最小.一般情况下,假设n个顶点分成两个集合:U(包含已落在生成树上 的结点)和V-U(尚未落在生成树上的顶点),则在所有连通U中顶点和V-U中顶点的边中选取权值最小的边. 例如:起始生成树上面就一个顶点.为了连通两个集合,在可选的边中,选择权值最小的.需要辅助数组,V-U中所有顶点. 具体实例如下图所示:求下图的最小生成树 我

数据结构-最小生成树-普里姆算法

转自https://blog.csdn.net/ZGUIZ/article/details/54633115 首先仍然是预定义: 1 #define OK 1 2 #define ERROR 0 3 #define Max_Int 32767 4 #define MVNum 100 5 6 typedef int Status; 7 typedef char VerTexType; 8 typedef int ArcType; 9 10 struct{ 11 VerTexType adjvex;

46. 蛤蟆的数据结构笔记之四十六普里姆算法

46. 蛤蟆的数据结构笔记之四十六普里姆算法 本篇名言:"手莫伸 ,伸手必被捉.党与人民在监督 ,万目睽睽难逃脱.汝言惧捉手不伸 ,他道不伸能自觉 , 其实想伸不敢伸 ,人民咫尺手自缩.-- 陈毅" 连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边.所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使得权值的和最小.构造连通网的最小代价生成树,即最小生成树(Minimum Cost Spanning Tree). 找连通图的最

ACM第四站————最小生成树(普里姆算法)

对于一个带权的无向连通图,其每个生成树所有边上的权值之和可能不同,我们把所有边上权值之和最小的生成树称为图的最小生成树. 普里姆算法是以其中某一顶点为起点,逐步寻找各个顶点上最小权值的边来构建最小生成树. 其中运用到了回溯,贪心的思想. 废话少说吧,这个其实是一个模板,直接套用就好!直接上题吧!这些东西多练就好! 一.最小生成树: 题目描述 求一个连通无向图的最小生成树的代价(图边权值为正整数). 输入 第 一行是一个整数N(1<=N<=20),表示有多少个图需要计算.以下有N个图,第i图的第

普里姆算法-prim

算法代码: C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 /* Prim算法生成最小生成树  */ void MiniSpanTree_Prim(MGraph MG) { int min, i, j, k; int adjvex[MAXVEX];/* 

图-&gt;连通性-&gt;最小生成树(普里姆算法)

文字描述 用连通网来表示n个城市及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,赋于边的权值表示相应的代价.对于n个定点的连通网可以建立许多不同的生成树,每一棵生成树都可以是一个通信网.现在,我们要选择这样一个生成树,使总的耗费最少.这个问题就是构造连通网的最小代价生成树(Minimum Cost Spanning Tree: 最小生成树)的问题.一棵生成树的代价就是树上各边的代价之和. 有多种算法可以构造最小生成树,其他多数都利用的最小生成的MST(minimum

普里姆算法(Prim)与最小生成树问题

普里姆算法 @anthor:QYX 普里姆算法在找最小生成树时,将顶点分为两类,一类是在查找的过程中已经包含在树中的(假设为 A 类),剩下的是另一类(假设为 B 类). 对于给定的连通网,起始状态全部顶点都归为 B 类.在找最小生成树时,选定任意一个顶点作为起始点,并将之从 B 类移至 A 类:然后找出 B 类中到 A 类中的顶点之间权值最小的顶点,将之从 B 类移至 A 类,如此重复,直到 B 类中没有顶点为止.所走过的顶点和边就是该连通图的最小生成树. 例如,通过普里姆算法查找图 2(a)