5.4最小生成树

None.gif #include  " stdafx.h "
None.gif#include 
< iostream.h >
None.gif#include 
< malloc.h >
None.gif
None.gif
int   const  vnum = 6 ;
None.gif
int   const  MAX = 32767 ;
None.gif
None.giftypedef 
struct  graph
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
int vexs[vnum];                                //顶点信息
InBlock.gif
    int arcs[vnum][vnum];                        //边的信息,因为现在是求带权图的最小生成树,所以其值为权值
InBlock.gif
    int vexnum;                                    //顶点数量
InBlock.gif
    int arcnum;                                    //边的数量
ExpandedBlockEnd.gif
}
GraphTp;
None.gif
None.giftypedef 
struct
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
int adjvex;                                    //代表新增结点的编号
InBlock.gif    
//代表新增结点对于i的结点的权值.
InBlock.gif    
//所谓的i就是Closege[vnum]数组中的值,vnum从0至vnum-1,代表第0至vnum-1个结点的编号,也即closege数组中的一个值,代表
InBlock.gif    
//U中的结点编号,对就于V-U中的某结点的权值.例如对于Closege[0]来说,adjvex=3,lowcost=1,则说明这是U中的第3个结点对于
InBlock.gif    
//于V-U中的第0个结点的权值为1
InBlock.gif
    int lowcost;                                
ExpandedBlockEnd.gif}
Closege[vnum];
None.gif
None.gif
void  CreateGraph(GraphTp  &  graph)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    graph.vexnum
=vnum;
InBlock.gif    graph.arcnum
=10;
InBlock.gif
InBlock.gif    
int k=0;
InBlock.gif    graph.vexs[k]
=k;
InBlock.gif    graph.arcs[k][
0]=MAX;
InBlock.gif    graph.arcs[k][
1]=6;
InBlock.gif    graph.arcs[k][
2]=1;
InBlock.gif    graph.arcs[k][
3]=5;
InBlock.gif    graph.arcs[k][
4]=MAX;
InBlock.gif    graph.arcs[k][
5]=MAX;
InBlock.gif
InBlock.gif    k
=1;
InBlock.gif    graph.vexs[k]
=k;
InBlock.gif    graph.arcs[k][
0]=6;
InBlock.gif    graph.arcs[k][
1]=MAX;
InBlock.gif    graph.arcs[k][
2]=5;
InBlock.gif    graph.arcs[k][
3]=MAX;
InBlock.gif    graph.arcs[k][
4]=3;
InBlock.gif    graph.arcs[k][
5]=MAX;
InBlock.gif
InBlock.gif    k
=2;
InBlock.gif    graph.vexs[k]
=k;
InBlock.gif    graph.arcs[k][
0]=1;
InBlock.gif    graph.arcs[k][
1]=5;
InBlock.gif    graph.arcs[k][
2]=MAX;
InBlock.gif    graph.arcs[k][
3]=5;
InBlock.gif    graph.arcs[k][
4]=6;
InBlock.gif    graph.arcs[k][
5]=4;
InBlock.gif
InBlock.gif    k
=3;
InBlock.gif    graph.vexs[k]
=k;
InBlock.gif    graph.arcs[k][
0]=5;
InBlock.gif    graph.arcs[k][
1]=MAX;
InBlock.gif    graph.arcs[k][
2]=5;
InBlock.gif    graph.arcs[k][
3]=MAX;
InBlock.gif    graph.arcs[k][
4]=MAX;
InBlock.gif    graph.arcs[k][
5]=2;
InBlock.gif
InBlock.gif    k
=4;
InBlock.gif    graph.vexs[k]
=k;
InBlock.gif    graph.arcs[k][
0]=MAX;
InBlock.gif    graph.arcs[k][
1]=3;
InBlock.gif    graph.arcs[k][
2]=6;
InBlock.gif    graph.arcs[k][
3]=MAX;
InBlock.gif    graph.arcs[k][
4]=MAX;
InBlock.gif    graph.arcs[k][
5]=6;
InBlock.gif
InBlock.gif    k
=5;
InBlock.gif    graph.vexs[k]
=k;
InBlock.gif    graph.arcs[k][
0]=MAX;
InBlock.gif    graph.arcs[k][
1]=MAX;
InBlock.gif    graph.arcs[k][
2]=4;
InBlock.gif    graph.arcs[k][
3]=2;
InBlock.gif    graph.arcs[k][
4]=6;
InBlock.gif    graph.arcs[k][
5]=MAX;
InBlock.gif
ExpandedBlockEnd.gif}

None.gif
None.gif
// 输入最小生成树,K为第K个机点,索引从0开始
None.gif
void  prim(GraphTp graph, int  k)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    Closege closege;
InBlock.gif    
int i;
InBlock.gif    
//初始化辅助数组,使其结点
InBlock.gif
    for(i=0;i<vnum;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
if (i!=k)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            closege[i].adjvex
=graph.vexs[k];
InBlock.gif            closege[i].lowcost
=graph.arcs[k][i];
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    closege[k].adjvex
=graph.vexs[k];
InBlock.gif    closege[k].lowcost
=0;
InBlock.gif    cout
<<"在U中首次加入顶点:"<<graph.vexs[k]<<endl;
InBlock.gif    
//控制次数,因为至多加个vnum个顶点,而初始时已加入一个,所以循环的次数为vnum-1次
InBlock.gif
    for (i=1;i<vnum;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
int min=-1;                                    //记录最小的权
InBlock.gif
        int v=-1;                                    //记录最小的权所对就的closege中的索引值
InBlock.gif        
//找到当前权值最小的边
InBlock.gif
        for(int j=0;j<vnum;j++)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (closege[j].lowcost>0 && closege[j].lowcost!=MAX)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if (min==-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    min
=closege[j].lowcost;
InBlock.gif                    v
=j;
ExpandedSubBlockEnd.gif                }

InBlock.gif                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
if (min>closege[j].lowcost)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        min
=closege[j].lowcost;
InBlock.gif                        v
=j;
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        cout
<<"在U中加入顶点:"<<v<<",权值为:"<<min<<endl;
InBlock.gif        
//修改closege[v].lowcost的值为0,代表共已经加入了U中
InBlock.gif
        closege[v].lowcost=0;
InBlock.gif        
//以新加入的顶点,与各顶点的权值,更新closege中的权值以及顶点,此为关键,这是保证closege这个辅助数组起作用的关键
InBlock.gif
        for(int k=0;k<vnum;k++
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (graph.arcs[v][k] < closege[k].lowcost)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                closege[k].lowcost 
= graph.arcs[v][k];
InBlock.gif                closege[k].adjvex 
= v;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
int  main( int  argc,  char *  argv[])
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    GraphTp g;
InBlock.gif    CreateGraph(g);
InBlock.gif    prim(g,
0);
InBlock.gif    
return 0;
ExpandedBlockEnd.gif}

None.gif    

对于这个普里姆算法,书上讲的有些不太细致,主要表现在U和TE的定义,以及对于辅助数组的作用的说明(也可能是我的理解能力差吧.).我看了两天都没有看明白书上的算法,我参考了严蔚敏的数据结构后,才逐渐的明白.
我对于书上不明白的地方写一下我自己的认识:
(1)U:是指对于新增加的顶点的集合,那么在初始状态时,我们加入一个新的顶点时,它的集合为:U={u0}.
(2)TE:是指最小生成树边的集合,也就是使权最小的边的集合.
(3)V-U:指在所有顶点中,去除U后所剩的顶点.
那么普里姆算法中,最简洁明了的说明是:"每新增一个顶点,就找到这个顶点到其它顶点的最小权,来更新辅助数组中的权值".这就涉及到了这个辅助数组的作用:
(4)辅助数组closedge:closedge数组的长度顶点的数量,其中记录的是U中顶点对V-U中顶点连通的权值.那么这个数组的更新就是在每向U中增加一个顶点的时候,就从这个新的顶点找到它与其它顶点连通的边的权值,与辅助数组中的记录的上次的顶点的权值做一个比较,如果小则更新之.在辅助数组中,lowcost=0代表此结点已经加入U中(例如closedge[0].lowcost=0,说明V0顶点已经加入到U中),lowcost=MAX表示尚未连通此顶点.

以我上面实现的代表为例,辅助数组的变化情况如下表:

closedge

V0

V1

V2

V3

V4

V5

U

Adjvex

lowcost

V0

0

V0

6

V0

1

V0

5

V0

V0

V0

Adjvex

lowcost

V0

0

V2

5

V0

0

V0

5

V2

6

V2

4

V0,V2

Adjvex

lowcost

V0

0

V2

5

V0

0

V5

2

V2

6

V2

0

V0,V2,V5

Adjvex

lowcost

V0

0

V2

5

V0

0

V5

0

V2

6

V2

0

V0,V2,V5,V3

Adjvex

lowcost

V0

0

V2

0

V0

0

V5

0

V1

3

V2

0

V0,V2,V5,V3,V1

Adjvex

lowcost

V0

0

V2

0

V0

0

V5

0

V1

0

V2

0

V0,V2,V5,V3,V1,V4

转载于:https://www.cnblogs.com/fxwdl/archive/2007/07/30/836037.html


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部