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的邻接矩阵: "); 18 DispMat(g); 19 printf(" "); 20 printf("普里姆算法求解结果: "); 21 prim(g,0); 22 printf(" "); 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 ",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(" "); 96 } 97 }
/*
图G的邻接矩阵:
∞ ∞ 1 ∞ 3 5
∞ ∞ 7 ∞ ∞ ∞
∞ ∞ ∞ 9 ∞ ∞
∞ ∞ ∞ ∞ ∞ 2
∞ ∞ ∞ 4 ∞ 6
∞ ∞ ∞ ∞ ∞ ∞
普里姆算法求解结果:
边(0,2)权为:1
边(0,4)权为:3
边(4,3)权为:6
边(3,5)权为:4
*/