|  | 
 
 发表于 2017-8-6 17:14:08
|
显示全部楼层 
| 两种求最小生成树的算法(Prim和Kruskal) Prim算法中有双重循环,外层是求n-1条边内层是在closedge[v].lowcost
 中求最小值和并列的求得当前加入点对closedge[]的影响。所以他的时间复杂度是O(
 ),它与途中边的数目没有关系,所以比较适合用在边比较稠密的图中。(顶点数相同,不管边数,都相同)
 Kruskal和他相对应,他的时间复杂度为O(eloge),与图中的结点数目无关,至于边的个数有关。所以适合用在稀疏图中。(边数一定,不管顶点数,复杂度都相同)
 求最小生成树的普里姆(Prim)算法中边上的权不可以为负,
 typedef struct {
 VertexType adjvex;
 VRType lowcost;
 }closedge[MAX_VERTEX_NUM];
 假设cost(u,w)表示边(u,w)上的权值,则对于集合 V-U 中每个顶点 w,
 closedge[LocateVex(G, w)].lowcost = Min{cost(u,w)|u∈U}
 void MiniSpanTree_PRIM( MGraph G, VertexType u,SqList& MSTree)
 {
 // G 为数组存储表示的连通网,按普里姆算法从顶点 u 出发构
 k = LocateVex ( G, u );
 for ( j=0; j
 if (j!=k) closedge[j] = { u, G.arcs[k][j].adj };//{adjvex,lowcost}
 closedge[k].lowcost = 0;       // 初始状态,U={u}
 for (i=1; i
 {  k = minimum(closedge);        // 求出T的下一个结点(图中第k顶点)
 // 此时closedge[k].lowcost =
 // Min{ closedge[vi].lowcost | closedge[vi].lowcost>0, vi∈V-U }
 printf(closedge[k].adkvex, G.vexs[k]); //输出生成编
 closedge[k].lowcost = 0;      // 第 k 顶点并入U集
 for (j=0; j
 if (G.arcs[k][j].adj     拓扑排序问题
 Status ToplogicalSort(ALGraph G)
 {
 FindIndegree(G,indegree);//求各点的入度放在Indegree[vnum];
 InitStack(S);
 for(i=0;i
 if(Indegree[i]= =0)
 push(S,i);
 count=0;
 while(!StackEmpty(S))
 { Pop(S,i); printf(i,G.vex[i].data); ++count;
 for(p=G..vex[i].firstarc; p; p=p->nextarc)
 { k=p->adjvex;
 Indegree[k]--;
 if( Indegree[k]= =0) push(S,k);
 }//for
 }//while
 if(count
 return ERROR;
 else
 return OK
 }
 算法分析:求各顶点的入度的时间复杂度为O(e),入度为零的点入栈O(n),在循环中,每个顶点进一次栈,出栈一次,入度减1操作在while共执行了e次,所以总的时间复杂度为O(n+e).
 当图中无环时,也可以利用深度优先遍历进行拓扑排序,因为图中无环,所以最先退出DFS函数的顶点即出度为零的点,是拓扑排序中最后一个顶点。由此,按DFS函数的先后记录下来的顶点序列即为逆向的拓扑有序序列。
 
 | 
 |