最小生成树

1)包含任务或问题描述和分析

最小生成树其实是最小权重生成树的简称。我们称求取该生成树的问题成为最小生成树问题。一个连通图可能有多个生成树。当图中的边具有权值时,总会有一个生成树的边的权值之和小于或者等于其它生成树的边的权值之和。

2)设计与实现

利用prim算法实现最小生成树,该算法思路与Dijsktra算法大致相同,不过Prim算法的最短是相较于整体而言的,所以我将Dijsktra算法稍作改进得到Prim算法

3)测试例子与结果分析

测试例子:(图片从网上找的,当做例子,非常直观)

 测试结果:

 

 4)带注释的源代码

#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 10
#define MAXROAD 999
/*

本算法由Dijsktra算法改变而来
*/
typedef struct{
	int i;
	int j;
	int weight;
}Node;//记录最小生成树的边和权重 
void Prim(int g[][MAX_SIZE],int num){//num为一开始知道的结点 
   int flag[MAX_SIZE]={0};//标志数组
    flag[num]=1;//将初始结点放入数组
   int i;
   Node tree[MAX_SIZE-1];//边的数量比结点少一 
   for(i=0;i<MAX_SIZE-1;i++){//一共循环MAX_SIZE-1次找到这么多的边
   Node temp;//记录最小的边
   temp.i=0;
   temp.j=0;
   temp.weight=MAXROAD;//初始化Node 
   int j,k;
   for(j=0;j<MAX_SIZE;j++)
   for(k=0;k<MAX_SIZE;k++)
   {
   	if(flag[j])
	   {//在已记录的结点中寻找边 
   	if(g[j][k]<temp.weight&&flag[k]==0){
   		temp.i=j;
   		temp.j=k;
   		temp.weight=g[j][k];
	   }
		}
	else break;
   	
   }
   flag[temp.j]=1;//标记数组更新 
   	tree[i].i=temp.i;
   	tree[i].j=temp.j;
   	tree[i].weight=temp.weight;//更新节点数组 
   } 
   for(i=0;i<MAX_SIZE-1;i++){
   	if(tree[i].weight!=MAXROAD)
   	printf("生成树的边为结点%d---->结点%d, 权值为%d\n",tree[i].i,tree[i].j,tree[i].weight);
   } 
   }
	
int main()
{
	int Grape[MAX_SIZE][MAX_SIZE]={0};//该图不是有向图,所以要更新为无向图 
	int i,j,num;
	printf("请输入i到j的路径并输入它的长度"); 
	while((scanf("%d%d%d",&i,&j,&num))!=EOF)
	{
		Grape[i][j]=num;
		Grape[j][i]=num;//对称为无向图 
		printf("请输入i到j的路径并输入它的长度"); 
		}	
	for(i=0;i<MAX_SIZE;i++)for(j=0;j<MAX_SIZE;j++)if(Grape[i][j]==0)Grape[i][j]=MAXROAD;
	Prim (Grape,0);
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值