有向无环图(Directed Acycling Graph):是图中没有回路(环)的有向图。
对工程的活动加以抽象:图中顶点表示活动,有向边表示活动之间的优先关系,这样的有向图称为顶点表示活动的网(Activity On Vertex Network ,AOV网) 。
拓扑排序
由某个集合上的一个偏序得到该集合上的一个全序的操作。
算法实现说明
◆ 采用正邻接链作为AOV网的存储结构;
◆ 设立堆栈,用来暂存入度为0的顶点;
◆ 删除顶点以它为尾的弧:弧头顶点的入度减1。
(1) 统计各顶点入度的函数
void count_indegree(ALGraph *G)
{
int k ;
LinkNode *p ;
for (k=0; k<G->vexnum; k++)
G->adjlist[k].indegree=0 ; /* 顶点入度初始化 */
for (k=0; k<G->vexnum; k++)
{
p=G->adjlist[k].firstarc ;
while (p!=NULL) /* 顶点入度统计 */
{
G->adjlist[p->adjvex].indegree++ ;
p=p->nextarc ;
}
}
}
(2) 拓扑排序算法
int Topologic_Sort(ALGraph *G, int topol[])
/* 顶点的拓扑序列保存在一维数组topol中 */
{
int k, no, vex_no, top=0, count=0, boolean=1 ;
int stack[MAX_VEX] ; /* 用作堆栈 */
LinkNode *p ;
count_indegree(G) ; /* 统计各顶点的入度 */
for (k=0; k<G->vexnum; k++)
if (G->adjlist[k].indegree==0)
stack[++top]=G->adjlist[k].data ;
do
{
if (top==0) boolean=0 ;
else
{
no=stack[top--] ; /* 栈顶元素出栈 */
topl[++count]=no ; /* 记录顶点序列 */
p=G->adjlist[no].firstarc ;
while (p!=NULL) /*删除以顶点为尾的弧*/
{
vex_no=p->adjvex ;
G->adjlist[vex_no].indegree-- ;
if (G->adjlist[vex_no].indegree==0)
stack[++top]=vex_no ;
p=p->nextarc ;
}
}
}while(boolean==0) ;
if (count<G->vexnum) return(-1) ;
else return(1) ;
}
算法分析:设AOV网有n个顶点,e条边,则算法的主要执行是:
◆ 统计各顶点的入度:时间复杂度是O(n+e) ;
◆ 入度为0的顶点入栈:时间复杂度是O(n) ;
◆ 排序过程:顶点入栈和出栈操作执行n次,入度减1的操作共执行e次,时间复杂度是O(n+e) ;
因此,整个算法的时间复杂度是O(n+e) 。