Minimum Spanning Trees

Kruskal’s algorithm

always union the lightest link if two sets haven't been linked

 1 typedef struct          
 2 {        
 3     char vertex[VertexNum];                                //顶点表         
 4     int edges[VertexNum][VertexNum];                       //邻接矩阵,可看做边表         
 5     int n,e;                                               //图中当前的顶点数和边数         
 6 }MGraph; 
 7  
 8 typedef struct node  
 9 {  
10     int u;                                                 //边的起始顶点   
11     int v;                                                 //边的终止顶点   
12     int w;                                                 //边的权值   
13 }Edge; 
14 
15 void kruskal(MGraph G)  
16 {  
17     int i,j,u1,v1,sn1,sn2,k;  
18     int vset[VertexNum];                                    //辅助数组,判定两个顶点是否连通   
19     int E[EdgeNum];                                         //存放所有的边   
20     k=0;                                                    //E数组的下标从0开始   
21     for (i=0;i<G.n;i++)  
22     {  
23         for (j=0;j<G.n;j++)  
24         {  
25             if (G.edges[i][j]!=0 && G.edges[i][j]!=INF)  
26             {  
27                 E[k].u=i;  
28                 E[k].v=j;  
29                 E[k].w=G.edges[i][j];  
30                 k++;  
31             }  
32         }  
33     }     
34     heapsort(E,k,sizeof(E[0]));                            //堆排序,按权值从小到大排列       
35     for (i=0;i<G.n;i++)                                    //初始化辅助数组   
36     {  
37         vset[i]=i;  
38     }  
39     k=1;                                                   //生成的边数,最后要刚好为总边数   
40     j=0;                                                   //E中的下标   
41     while (k<G.n)  
42     {   
43         sn1=vset[E[j].u];  
44         sn2=vset[E[j].v];                                  //得到两顶点属于的集合编号   
45         if (sn1!=sn2)                                      //不在同一集合编号内的话,把边加入最小生成树   
46         {
47             printf("%d ---> %d, %d",E[j].u,E[j].v,E[j].w);       
48             k++;  
49             for (i=0;i<G.n;i++)  
50             {  
51                 if (vset[i]==sn2)  
52                 {  
53                     vset[i]=sn1;  
54                 }  
55             }             
56         }  
57         j++;  
58     }  
59 }

Prim’s algorithm

maintain a key of each vertex to represent the lightest  link which connected the vertex

initial all the key as maximum, begin from a vertex and update the adjoin vertex key.

#define MAX  100000
#define VNUM  10+1                                             //这里没有ID为0的点,so id号范围1~10

int edge[VNUM][VNUM]={/*输入的邻接矩阵*/};
int lowcost[VNUM]={0};                                         //记录Vnew中每个点到V中邻接点的最短边
int addvnew[VNUM];                                             //标记某点是否加入Vnew
int adjecent[VNUM]={0};                                        //记录V中与Vnew最邻近的点


void prim(int start)
{
     int sumweight=0;
     int i,j,k=0;

     for(i=1;i<VNUM;i++)                                      //顶点是从1开始
     {
        lowcost[i]=edge[start][i];
        addvnew[i]=-1;                                         //将所有点至于Vnew之外,V之内,这里只要对应的为-1,就表示在Vnew之外
     }

     addvnew[start]=0;                                        //将起始点start加入Vnew
     adjecent[start]=start;
                                                 
     for(i=1;i<VNUM-1;i++)                                        
     {
        int min=MAX;
        int v=-1;
        for(j=1;j<VNUM;j++)                                      
        {
            if(addvnew[j]!=-1&&lowcost[j]<min)                 //在Vnew之外寻找最短路径
            {
                min=lowcost[j];
                v=j;
            }
        }
        if(v!=-1)
        {
            printf("%d %d %d
",adjecent[v],v,lowcost[v]);
            addvnew[v]=0;                                      //将v加Vnew中

            sumweight+=lowcost[v];                             //计算路径长度之和
            for(j=1;j<VNUM;j++)
            {
                if(addvnew[j]==-1&&edge[v][j]<lowcost[j])      
                {
                    lowcost[j]=edge[v][j];                     //此时v点加入Vnew 需要更新lowcost
                    adjecent[j]=v;                             
                }
            }
        }
    }
    printf("the minmum weight is %d",sumweight);
}
原文地址:https://www.cnblogs.com/wujunde/p/7161138.html