最小生成二叉树-prim算法

1.prim算法:一种计算生成最小生成树的方法,它的每一步都会为一棵生长中的树添加一条边.

2.时间复杂度:

    通过邻接矩阵图表示的简易实现中,找到所有最小权边共需O(V)的运行时间。使用简单的二叉堆与邻接表来表示的话,普里姆算法的运行时间则可缩减为 O(ElogV),其中E为连通图的边数,V为顶点数。如果使用较为复杂的斐波那契堆,则可将运行时间进一步缩短为O(E+VlogV),这在连通图足够 密集时(当E满足Ω(VlogV)条件时),可较显著地提高运行速度。

3.代码实现:

 1 #include <stdio.h>
 2 #define    MAXV 100  //最大顶点个数
 3 #define INF 32767 //INF表示∞
 4 typedef struct                  
 5 {      int edges[MAXV][MAXV];//邻接矩阵
 6        int vexnum,arcnum;   //顶点数,弧数
 7 } MGraph;//图的邻接矩阵类型
 8 
 9 void init(MGraph &g);//初始化邻接矩阵
10 void DispMat(MGraph g);//输出邻接矩阵g
11 void prim(MGraph g,int v);
12 int main()
13 {
14     int u=3;
15     MGraph g;//图的邻接矩阵
16     init(g);//初始化邻接矩阵
17     printf("图G的邻接矩阵:\n");
18     DispMat(g);
19     printf("\n");
20     printf("普里姆算法求解结果:\n");
21     prim(g,0);
22     printf("\n");
23     return 0;
24 }
25 
26 
27 void prim(MGraph g,int v)//从v号节点开始---生成最小生成树
28 {
29     //(V-U)---未加入最小生成树的点
30     //U---已加入最小生成树的点
31     int i,j,k;
32     int MinCost[MAXV];   //(V-U)中各点离U的最小距离
33     int MinCostNum[MAXV];//(V-U)中各点离U的最小距离对应在U中的点
34     int min;//min记录离U最近的距离
35     MinCost[v]=0;//v加入U
36     for (i=0;i<g.vexnum;i++) //初始化MinCost[]和MinCostNum[]
37     {    
38         MinCost[i]=g.edges[v][i];//每个节点距v的值
39         MinCostNum[i]=v;//(V-U)中的节点i距U中最近的点是v
40     }
41     for (i=1;i<g.vexnum;i++)          
42     {   
43         min=INF;
44         for (j=0;j<g.vexnum;j++)//在(V-U)中找出离U最近的顶点k
45                if (MinCost[j]!=0 && MinCost[j]<min) //未加入U(即V-U)中的点且距离U最近
46             {    
47                 min=MinCost[j];
48                 k=j; //k记录离U最近的顶点
49             }
50             if(min!=INF)//(V-U)中离U最近点k--距U中最近的一个点是MinCostNum[k]
51                 printf("边(%d,%d)权为:%d\n",MinCostNum[k],k,min);
52             MinCost[k]=0;//标记k已经加入U
53             //更新(V-U)中的点/////////////////////
54             for (j=0;j<g.vexnum;j++)//由于顶点k的新加入而修改数组lowcost和closest
55                    if (MinCost[j]!=0 && g.edges[k][j]<MinCost[j]) 
56                 {    
57                     MinCost[j]=g.edges[k][j];
58                     MinCostNum[j]=k; 
59                 }
60             //经典之处///////////////////////////////////////
61     }
62 }
63 void init(MGraph &g)
64 {
65     int i,j;
66     g.vexnum=6;g.arcnum=10;
67     int A[MAXV][11];    
68     for (i=0;i<g.vexnum;i++)
69         for (j=0;j<g.vexnum;j++)
70             A[i][j]=INF;
71     //数据结构书P189---图7.34
72     A[0][2]=1;A[0][4]=3;A[0][5]=7;
73     A[1][2]=9;
74     A[2][3]=2;
75     A[3][5]=4;
76     A[4][3]=6;A[4][5]=8;
77     /*for (i=0;i<g.vexnum;i++)//使邻接矩阵对称
78         for (j=0;j<g.vexnum;j++)
79             A[j][i]=A[i][j];*/
80     for (i=0;i<g.vexnum;i++)//建立邻接矩阵
81         for (j=0;j<g.vexnum;j++)
82             g.edges[i][j]=A[i][j];
83 
84 }
85 void DispMat(MGraph g)//输出邻接矩阵g
86 {
87     int i,j;
88     for (i=0;i<g.vexnum;i++)
89     {
90         for (j=0;j<g.vexnum;j++)
91             if (g.edges[i][j]==INF)
92                 printf("%3s","∞");
93             else
94                 printf("%3d",g.edges[i][j]);
95         printf("\n");
96     }
97 }
/*
图G的邻接矩阵:
 ∞ ∞ 1 ∞ 3 5
 ∞ ∞  7 ∞ ∞ ∞
 ∞ ∞ ∞ 9 ∞ ∞
 ∞ ∞ ∞ ∞ ∞ 2
 ∞ ∞ ∞ 4 ∞ 6
 ∞ ∞ ∞ ∞ ∞ ∞
普里姆算法求解结果:
边(0,2)权为:1
边(0,4)权为:3
边(4,3)权为:6
边(3,5)权为:4
*/

 

posted on 2016-05-25 21:21  Cultivate  阅读(2470)  评论(0编辑  收藏  举报

导航