数据结构之AOV网与拓扑排序

AOV网(Activity On Vertex Network )

网:带权图。若在带权的有向图中,以顶点表示事件,以边(或者弧)表示活动,弧的权值表示活动的开销,则此带权有向图称为用边表示活动的网,简称:(AOV网(Activity On Vertex Network )。

关键路径

如果用AOV网表示一个工程,那么正常情况下工程只有一个开始点和一个结束点,因此AOV网中只有一个入度为0的点,称为源点;一个出度为0的点,称为汇点。
AOV网具有以下两个性质:
1、只有在某顶点所代表的事情发生后,从该顶点出发的弧所代表的活动才能开始。
2、只有在进入某顶点的各弧所代表的活动都已经结束时,该顶点所代表的事情才能发生。

由于AOV网中的某些活动可以并行进行,所以完成整个工程最短时间是从源点到汇点的最大路径长度。具有最大路径长度的路径称为关键路径,关键路径上的活动称为关键活动。

一个无环的有向图称为有向无环图,在AOV网中不存在有向环(或者称有向回路)

对于给定的AOV网,首先判断网中是否存在环路,只有有向无环图才具有现实意义。检查AOV网中是否存在回路的方法就是拓扑排序。

拓扑排序后,会得到一个有向图的顶点序列。

拓扑排序的实现

1、从网中选择一个没有前驱的顶点(入度为0)并且输出它。
2、从网中删去该顶点,并且删去从该顶点发出的全部有向边
3、重复上述两步,直到剩余的网中不存在没有前驱的顶点为止。

此操作有两种结果: 一、网中全部顶点都被输出,这说明网中不存在有向回路; 二、网中顶点未被全部输出,剩余的顶点均有前驱顶点,这说明网中存在有向回路。

这里写图片描述

由上图可得到的拓扑序列为C2、C1、C4、C3、C5、C7、C6。当然,如果输出是选取的顶点不同,那么拓扑序列也就不唯一了。

show the code

#include<stdio.h>
#include<malloc.h>
#define max 100
typedef struct arcnode
{
    int adjvex;
    struct arcnode*next;
}arcnode;
typedef struct 
{
    int vertex;
    arcnode*firstarc;
}vexnode;
vexnode adjlist[max];
int creatadjlist()
{
    arcnode*ptr;
    int arcnum,vexnum,k,v1,v2;
    printf("input vexnum and arcnum:");
    scanf("%d,%d",&vexnum,&arcnum);
    for(k=1;k<=vexnum;k++)
    {
        adjlist[k].firstarc=NULL;
        adjlist[k].vertex=0;
    }
    for(k=1;k<=arcnum;k++)
    {
        printf("v1,v2=");
        scanf("%d,%d",&v1,&v2);
        ptr=(arcnode*)malloc(sizeof(arcnode));
        ptr->adjvex=v2;
        ptr->next=adjlist[v1].firstarc;
        adjlist[v1].firstarc=ptr;
        adjlist[v2].vertex++;
    }
    return vexnum;
}
toposort(int n)
{
    int queue[max];
    int front=0,rear=0;
    int v,w,m;
    arcnode*p;
    m=0;
    for(v=1;v<=n;v++)
        if(adjlist[v].vertex==0)
        {
            rear=(rear+1)%max;
            queue[rear]=v;
        }
        printf("the toposort:\n");
        while(front!=rear)
        {
            front=(front+1)%max;
            v=queue[front];
            printf("%d ",v);
            m++;
            p=adjlist[v].firstarc;
            while(p!=NULL)
            {
                w=p->adjvex;
                adjlist[w].vertex--;
                if(adjlist[w].vertex==0)
                {
                    rear=(rear+1)%max;
                    queue[rear]=w;
                }
                p=p->next;
            }
        }
        if(m<n)
            printf("the toposort is fail.");
}
int main()
{
    int n;
    n=creatadjlist();
    toposort(n);
    return 0;
}

运行截图

这里写图片描述

总结
用邻接表创建一个图就不细说了,拓扑排序,用一个队列,在for里面循环检测入度为0的顶点并入队;然后输出入度为0的顶点并计数;删除由顶点v出发的所有的弧;
最后比较计数值与顶点总数,判断是否拓扑成功。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值