最小生成树算法(一)--对prim算法的理解

来源:互联网 发布:阿里云主机 smtp 编辑:程序博客网 时间:2024/05/22 02:09


7.4.1 prim算法

 

 

              用prim算法求图的最小生成树:

1)      由两个数组记录prim求最小生成树的过程中所需的信息

a)      Lowcost[Max],记录最小生成树中每个【叶子结点】和【其他顶点】组成的所有边的权重,没有边的,权重就是

                                           i.           长度就是顶点的个数

b)      Adjvex[Max],记录Lowcost[Max]数组中,每条边所对应的一个顶点,也就是说,这个边是属于这个顶点的,Adjvex[Max]记录的就是这个顶点在图中的下标(可以比喻成是一个线性函数,Adjvex[Max]就是自变量的集合,Lowcost[Max]就是函数值的集合)

c)       Adjvex[Max] 的 元素 与 元素对应的下标构成的边,是在最小生成书中的,对应下标的Adjvex[Max]的元素,就是这条边的权重

d)      有这么几个要解决的问题:

                                           i.           选出Lowcost[Max]数组中的元素

1.       Lowcost[0] = 0 ,Adjvex[0] = 0  -> 将V0添加到最小生成树中,也就是最小生成树的根

2.       Lowcost数组的初始值就是【V0参与生成所有边的权重】的集合

                                          ii.           根据Lowcost[Max]数组数据与 邻接矩阵中,第【最小生成树新添加顶点的下标】行的数据比较,确定Adjvex[Max]数组的元素,并且将较小的边,替换Lowcost[Max]中对应下标的边(相当于是设置自变量,和函数值)

                                         iii.           选出Lowcost[Max]数组后,找出最小的权重的边,并添加到最小生成树,权重为0,就算是添加到最小生成树中,所以每次选出之后,都要将Lowcost[i] = 0,k =i (记录最小权重边的下标)(一旦成为最小生成树的一部分,权重(函数值)=0)

(Adjvex[k],k)就是当前的最小权重边

                                         iv.           将邻接矩阵中的第k行的数据与 Lowcost数组中的比较

满足(lowcost[j] !=0 && arc[k][j] < lowcost[j])

è lowcost[j] = arc[k][j]  Adjvex[j] = k

这其实就是将【新添加到最小生成树中的边】的【另一个顶点(比如V1)所参加生成的边中(权重信息存储在邻接矩阵的第1行),权重小于lowcost对应的值的边】添加到lowcost数组中

                                   lowcost[j]!=0 表示已经在最小生成树中的边不参与比较

2)      代码解析:

       void MiniSpanTree_Prim(MGraph G)

       {

              int min,i,j,k;

              int adjvex[Max];                  //存储lowcost[]存储的边的一个顶点,元素与对应下标组成边

              int lowcost[Max];                //存储最小生成树所有叶子结点的所有边的权重

              lowcost[0] = 0;                    //将V0放到最小生成树中,V0到V0是没有权值的

              adjvex[0] = 0;                      // V0到V0是没有边的

              //初始化两个数组

              for(i = 1;i < G.numVertex; i++)

              {

                     lowcost[i] = G.arc[0][i];

                     adjvex[i]= 0;

              }

              //循环图中的每一个顶点

              for(i = 1; i < G.numVertex;i++)

              {

                     min = 65535;

                     j = 1;             //因为V0已经在最小生成树中,所以从下标为1的顶点开始

                     k = 0;

                     while(j < G.numVertex)

                     {

                            // lowcost[i] != 0 表示顶点没有在最小生成树中

                            // lowcost[i] <min 找出当前lowcost数组中最小的元素

                            if(lowcost[i] != 0&& lowcost[i] < min)

                            {

                                   min =lowcost[i];

                                   k = j;

                            }

                            j++;

                     }

                     cout << adjvex[k]<< k;      //可以是其他的操作

                     lowcost[k] = 0;                    //将lowcost数组中最小元素置0(也就是附在顶点k上的某条边的权重置0,表示k顶点加入最小生成树中)

                     //更新lowcost数组元素,将现有的lowcost数组中的元素,依次与邻接矩阵第k行元素比较,较小的就替换lowcost数组中对应的元素

                     // lowcost[j] != 0表示已经在最小生成树中的顶点不用遍历

                     for(j = 1; j <G.numVertex; j++)

                     {

                            if(lowcost[j] != 0&& G.arc[k][j] < lowcost[j])

                            {

                                   //依次与邻接矩阵第k行元素比较,较小的就替换lowcost数组中对应的元素

                                   lowcost[j] =G.arc[k][j];

                                   adjvex[j] =k;         //将下标为k的顶点存入adjvex数组,k,j 组成一条边

                            }

                     }

              }            

       }

0 0