首页 > 其他 > 详细

最小生成树

时间:2020-02-04 15:10:35      阅读:93      评论:0      收藏:0      [点我收藏+]

一个无向图G的最小生成树是由该图的那些连接G的所有顶点的边构成的树,且其总价值(边的权值的和)最低。

用Prim算法实现最小生成树

  先把图看作许多个零散的顶点,顶点之间无联系,然后选一个作为树的开始顶点。算法的每一阶段都通过选择边(u,v),使得(u,v)的值是所有u在树上但v不在树上的边中的最小者,找出这样一个新的顶点并把它添加到这棵树上。

代码如下:

  1 #include <iostream>
  2 
  3 using namespace std;
  4 #define    MAX_VERTEX_NUM 10//最大顶点个数
  5 #define INF 32768
  6 
  7 //邻接表
  8 struct ENode//边结点
  9 {
 10     int index;//边所指向的点的序号
 11     int info;//记录权值
 12     struct ENode* next;//指向下一条边
 13 };
 14 struct VNode//顶点结点
 15 {
 16     char data;//顶点名称
 17     ENode* first;//指向顶点的第一个邻边
 18 };
 19 struct AGraph//记录图的信息
 20 {
 21     int vexnum, arcnum;//顶点数和边数
 22     VNode p[MAX_VERTEX_NUM];//顶点数组
 23 };
 24 
 25 int LocateVex(AGraph *G, char ch)
 26 {
 27     for (int i = 0; i < G->vexnum; i++)
 28         if (ch == G->p[i].data)
 29         {
 30             return i;
 31             break;
 32         }
 33     return -1;
 34 }
 35 //创建邻接表
 36 void CreateAGraph(AGraph *G)
 37 {
 38     int i, j, info;
 39     char v1, v2;
 40     cout << "请输入顶点个数:" << endl; cin >> G->vexnum;
 41     cout << "请输入边的个数:" << endl; cin >> G->arcnum;
 42     cout << "构造顶点:" << endl;
 43     for (int i = 0; i < G->vexnum; i++)//构造顶点数组
 44     {
 45         cin >> G->p[i].data;
 46         G->p[i].first = NULL;
 47     }
 48     cout << "构造邻接表:" << endl;
 49     for (int k = 0; k < G->arcnum; k++)//无向图
 50     {
 51         cin >> v1 >> v2 >> info;
 52         i = LocateVex(G, v1);
 53         j = LocateVex(G, v2);
 54         ENode *E = (ENode*)malloc(sizeof(ENode));
 55         E->index = j;//边(i,j)
 56         E->info = info; 
 57         E->next = G->p[i].first;//头插法
 58         G->p[i].first = E;
 59         ENode *E1 = (ENode*)malloc(sizeof(ENode));
 60         E1->index = i;//边(j,i)
 61         E1->info = info;
 62         E1->next = G->p[j].first;
 63         G->p[j].first = E1;
 64     }
 65 }
 66 //
 67 struct TableNode
 68 {
 69     int known;//顶点是否已处理
 70     int dist;//距离
 71     char path;//记录该顶点的前驱顶点
 72 };
 73 typedef TableNode Table[MAX_VERTEX_NUM];
 74 //初始化Prim算法中使用的表
 75 void CreateTable(Table T,int start)//start为起始的顶点
 76 {
 77     for (int i = 0; i < MAX_VERTEX_NUM; i++)
 78     {
 79         T[i].known = 0;//顶点未处理
 80         T[i].dist = INF;//距离为INF
 81         T[i].path = 0;//表示前面没接顶点
 82     }
 83     T[start].dist = 0;
 84 }
 85 //Prim算法
 86 void Prim(AGraph* G, Table T,int start)
 87 {
 88     int minindex = start;
 89     int count = 0;//记录已标记的顶点个数
 90     while (count != G->vexnum)//还有顶点未处理
 91     {
 92         int mindist=INF;
 93         int v=minindex;
 94         T[v].known = 1; 
 95         count++;
 96         //对相邻顶点进行调整
 97         if (G->p[v].first != NULL)
 98         {
 99             ENode* e = G->p[v].first;
100             while (e)
101             {
102                 if (T[e->index].known == 0 && T[e->index].dist > e->info)
103                 {
104                     T[e->index].dist = e->info;
105                     T[e->index].path = G->p[v].data;
106                 }
107                 e = e->next;
108             }
109         }
110         //找出表中dist最小且未处理过的顶点的编号minindex,将其入队
111         for (int i = 0; i<G->vexnum; i++)
112             if(T[i].known == 0)
113                 if (T[i].dist < mindist)
114                 {
115                     minindex = i;
116                     mindist = T[i].dist;
117                 }            
118     }
119 }
120 //打印表
121 void PrintTable(AGraph* G,Table T)
122 {
123     cout << "执行Prim后的Table:" << endl;
124     for (int i = 0; i < G->vexnum; i++)
125         cout << T[i].known << " " << T[i].dist << " " << T[i].path << endl;
126 }
127 int main()
128 {
129     int start = 0;
130     AGraph* G = (AGraph*)malloc(sizeof(AGraph));
131     CreateAGraph(G);
132     Table T;
133     CreateTable(T, start);
134     Prim(G, T, start);
135     PrintTable(G, T);
136     system("pause");
137     return 0;
138 }

 创建的无向图和其最小生成树如下:

技术分享图片

 运行结果:

技术分享图片

 

最小生成树

原文:https://www.cnblogs.com/cs0915/p/12259172.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!