最小生成树图文详解(Prim算法)

最小生成树

就像几个村庄都不相通, 要修路, 怎么修, 这个花的钱最少, 这种最优选择就是最小生成树

 

设G = (V, E)是无向连通图(V是结点集, E是边集),相对于村庄例子,V就是那些村庄的集合,E就是村庄之间路的集合

设T = (U, TE)是最小生成树, U是结点集,TE是边集

Prim算法的思想

  • 首先在V集合中任意选择一个村庄作为起始点i,将i点并入U集合中,然后在找一个修路到i村庄最便宜的j村庄并入集合TE中(在所有i∈U, j∈V-U中找一条代价最小的边(i,j) 
  • 重复第一步的操作

 

设数组adjvex[n]表示候选最短边的领接点

设数组lowcast[n]表示权值

其值如下,含义是候选最短边(i,j)的权值为w,其中iV-U , j∈U

adjvex[i] = j

lowcost[i] = w

 

介绍了这么多抽象概念,还是看图理解一下Prim算法的流程

 

 

 

 

C语言实现

#include<stdio.h>
#define MaxSize 100
struct MGraph {
  int vertex[MaxSize];// 定义存放顶点的一维数组
  int edge[MaxSize][MaxSize]; // 存放边的二维数组
  int vertexNum, edgeNum; 
};
int MinEdge(int   *lowcost, int num) {
  int min = 9999;
  int index = -1;
  for(int i = 0; i < num; i++) {
    if(lowcost[i] < min && lowcost[i] != 0) {
      min = lowcost[i];
      index = i;
    }
  }
  return index;
}
void Prim(MGraph *G, int v) {// 从顶点V出发 
  int i, j, k;
  int adjvex[MaxSize], lowcost[MaxSize];
  for (i = 0; i < G -> vertexNum; i++) {// 初始化 
    lowcost[i] = G -> edge[v][i];
    adjvex[i] = v;
  }
  lowcost[v] = 0; /* 将顶点v加入集合*/
  for (k = 1; k < G -> vertexNum; k++) {
    j = MinEdge(lowcost, G -> vertexNum);// 寻找最短边的领接点
    printf("(%d, %d)%d ", j, adjvex[j], lowcost[j]);// 输出最短边(j, i)及其权值 
    lowcost[j] = 0; /* 将顶点j加入集合*/
    for (i = 0; i < G ->vertexNum; i++) { /* 更新 */
      if (G -> edge[i][j] < lowcost[i]) {
        lowcost[i] = G -> edge[i][j];
        adjvex[i] = j;
      } 
    }
  }
}

int main() {
  MGraph g;
  MGraph *G = &g;
  G -> vertexNum = 6;//6个顶点
  G -> edgeNum = 9;// 9条边
  for(int i = 0; i < 6; i++)
    for(int j = 0; j < 6; j++)
      G -> edge[i][j] = 9999;// 无限大 
  G -> edge[0][1] = 34;  G -> edge[1][0] = 34;
  G -> edge[0][2] = 46;  G -> edge[2][0] = 46;
  G -> edge[0][5] = 19;  G -> edge[5][0] = 19;
  G -> edge[1][4] = 12;  G -> edge[4][1] = 12;
  G -> edge[2][3] = 17;  G -> edge[3][2] = 17;
  G -> edge[2][5] = 25;  G -> edge[5][2] = 25;
  G -> edge[3][4] = 38;  G -> edge[4][3] = 38;
  G -> edge[3][5] = 25;  G -> edge[5][3] = 25;
  G -> edge[4][5] = 26;  G -> edge[5][4] = 26;
  Prim(G, 0);
}

 

 

 

 

 

 

 

 

参考书籍:数据结构(王红德 皮德常)

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值