Prim算法

Prim算法的思想:从图中任意取出一个顶点,把它当成一棵树,然后从与这颗树相接的边中选取一条最短(权值最小)的边,并将这条边及其多连接的顶点也并入这棵树中,此时得到了一棵有两个顶点的树,然后从与这棵树相接的边中选取一条最短的边,并将这条边及其所连顶点并入当前树中,得到一棵含有3个顶点的树,一次类推。。。

代码如下:

/*构造一张无向图*/
#ifndef MGRAPH_H_
#define MGRAPH_H_

#define INF 9999
#define maxSize 30
typedef int VertexType;	
typedef struct 
{
	int edges[maxSize][maxSize];
	int n,e;
	VertexType vex[maxSize];
}MGraph;

void CreateMGraph( MGraph * G)
{
	int i,j,k,weight;
	int n1,n2;
	
	printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");
	scanf("%d,%d",&(G->n),&(G->e));
	//给顶点编号
	for(i=0;i<G->n;i++)
		G->vex[i]=i;
	for(i=0;i<G->n;i++)
		for(j=0;j<G->n;j++)
			{
                        G->edges[i][j]=INF;
                        if(i==j)
                            G->edges[i][j]=0;//邻接矩阵的对角线为0
                        }
        printf("请输入对应的边的结点号和边的权值(i,j,w)\n");
	for(k=0;k<G->e;k++)
	{
		printf("第%d条边的结点号和权值:",k+1);
		scanf("%d,%d,%d",&i,&j,&weight);
		G->edges[i][j]=weight;
		G->edges[j][i]=weight;
	}
}
#endif

头文件MGraph.h结束


#include<stdio.h>
#include"MGraph.h"

typedef enum {NO,YES} Bool;
Bool vset[maxSize];
void Prim(MGraph const G,int const v0,int * sum)
{
    int lowcost[maxSize],v;//lowcost保存的是当前生成树到顶点的最短边的权值
    int i,j,k,min;
    v=v0;
    for(i=0;i<G.n;i++)
    {
        lowcost[i]=G.edges[v0][i];
        vset[i]=NO;
    }
    vset[v0]=YES;
    printf("%d",v0);
    *sum=0;//sum 清零用来累计树的权值
    for (i=0;i<G.n-1;i++)
    {
                
        min=INF;
        /*下面这个循环用于选出候选边中的最小者*/
        for(j=0;j<G.n;j++)
            if(vset[j]==NO && lowcost[j]<min)
            {
                min=lowcost[j];
                k=j;
            }
        vset[k]=YES;
        v=k;
        *sum=(*sum)+min;
        printf(" %d",k);
        /*以刚并入的顶点V为媒介更新候选边*/
        for(j=0;j<G.n;j++)
            if(vset[j]==NO&&G.edges[v][j]<lowcost[j])
                lowcost[j]=G.edges[v][j];
    }
}

void main(void)
{
    MGraph G;
    int sum=0;
    int i;
    CreateMGraph(&G);
    Prim(G,0,&sum);
    printf("%d",sum);
    
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值