普利姆算法实现最小生成树(C语言版)

#include <stdio.h>
#include <stdlib.h>

#define MAX 100
#define INFINITY 10000

typedef struct graph{
    char vexs[MAX]; //顶点集合
    int vexnum;           // 顶点数
    int arcnum;           // 边数
    int arc[MAX][MAX]; //邻接矩阵
    int visited[MAX];//设置访问数组
}MGraph,*PGraph;

typedef struct{
    int adjvertex;
    int lowcost;
}CloseEdge[MAX];//PRIM算法的核心结构体


void create_graph(PGraph G){
    int i,j,k,w;
    printf("请输入顶点数和边数:");
    scanf("%d%d",&G->vexnum,&G->arcnum);
    getchar();
    for(i=0;i<G->vexnum;i++){
        printf("请输入%d个顶点的信息\n",i+1);
        scanf("%c",&G->vexs[i]);
        getchar();
    }
    
    //邻接矩阵的初始化,对角线为0,其他地方为infinity
    for(i=0;i<G->vexnum;i++){
        for (j=0; j<G->vexnum; j++) {
            if(i==j)
                G->arc[i][j] = 0;
            else
                G->arc[i][j] = INFINITY;
        }
        G->visited[i] = 0;
    }
    //对邻接矩阵进行赋值
    for(k=0;k<G->arcnum;k++){
        printf("输入边(vi,vj)的下标i,j以及权值w:");
        scanf("%d%d%d",&i,&j,&w);
        G->arc[i][j] = w;
        G->arc[j][i] = w;
    }
}


void MiniSpanTree_PRIM(MGraph *G, int u,CloseEdge closedge){
    //u为起点
    int i,j,w,k;
    int count=0;
    //初始化工作,lowcost中存入当前节点到其他节点的权值
    for(i=0;i<G->vexnum;i++){
        if(i!=u){
            closedge[i].adjvertex=u;//邻接点为u
            closedge[i].lowcost=G->arc[u][i];//将u与i的权值存入lowcost
        }
    }
    closedge[u].lowcost = 0;//访问过的u则lowcost=0,通过此标记便不再访问u;
    //寻找权值最小的顶点
    for(i=0;i<G->vexnum;i++){
        w=INFINITY;
        //第一个内循环得到权值最小顶点
        for(j=0;j<G->vexnum;j++){
            if(closedge[j].lowcost!=0&&closedge[j].lowcost<w){
                w=closedge[j].lowcost;
                k=j;
            }
        }//查询到到已经访问顶点距离最近的顶点k
        closedge[k].lowcost=0;//访问过的节点标记为0;
        //接下来也是该算法的精髓,比较新找到节点与j的权值是否比原先lowcost小,小的话则进行替换。
        for(j=0;j<G->vexnum;j++){
            if(G->arc[k][j]<closedge[j].lowcost){
                //更新操作
                closedge[j].adjvertex=k;
                closedge[j].lowcost=G->arc[k][j];
            }
        }
    }// 外循环结束

    //输出操作,就可以自己随意设计输出了.
    for(i=0;i<G->vexnum;i++)
        if(i!=u){
            printf("输出构建的最小生成树为:");
            printf("%c->%c,%d\n",G->vexs[i],G->vexs[closedge[i].adjvertex],G->arc[i][closedge[i].adjvertex]);//输出最短路径相关顶点信息以及他们之间的权值
            count+=G->arc[i][closedge[i].adjvertex];
        }
        printf("\n");
        printf("此最小生成树的总权值为:%d",count);
        printf("\n");
    }

int main(){
    MGraph G;
    CloseEdge a[MAX];
    create_graph(&G);
    MiniSpanTree_PRIM(&G,0,a[99]);
}

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值