拓扑排序

久未见 提交于 2020-01-12 09:34:31

定义

在一个有向图中找一个拓扑序列的过程称为拓扑排序

拓扑排序: 设 G=(V,E)是一个具有n个顶点的有向图,V中的顶点序列v1,v2,…,vn,称为一个拓扑序列。

方法

拓扑排序方法如下:

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

这样操作的结果有两种:一种是图中全部顶点都被输出,即该图中所有顶点都在去拓扑序列中,这说明图中不存在回路;另一种就是图中顶点未被全部输出,这说明图中存在回路。所以可以通过对一个有向图进行拓扑排序,看是否产生全部顶点的拓扑序列来确定该图中是否存在回路问题。

对于给定的有向图,可以采用邻接表作为存储结构,邻接表定义中的VNode类型修改如下:

typedef struct
{
	Vertex data;			//顶点信息
	int count;				//增加数据域:存放顶点入度
	ArcNode * firstarc;		//指向第一个邻接点
}VNode;					//头结点类型

对应的拓扑排序算法如下:

void TopSort(AdjGraph *G)       //拓扑排序算法
{ int i,j;
    int St[MAXV].top=-1;        //栈St的指针为top
    ArcNode *p;
    for(i=0;i<G->n;i++)         //入度置初值0
        G->adjlist[i].count=0;
    for(i=0;i<G->n;i++)         //求多有顶点的入度
    {
        p=G->adjlist[i].firstarc;
        while(p!=NULL)
        {
            G->adjlist[p->adjvex].count++;
            p=p->nextarc;
        }
    }
    for(i=0;i<G->n;i++)         //将入度为0的顶点进栈
        if(G->adjlist[i].count==0)
        {
            top++;
            St[top]=i;
        }
        while(top>-1)               //栈空不循环
    {
        i=St[top];top==;        //出栈一个顶点i
        printf("%d",i);         //输出该顶点
        p=G->adjlist[i].count;  //找第一个邻接点
        while(p!=NULL)          //将顶点i的出边邻接点的入度减1
        {
            j=p->adjvex;
            G->adjlist[j].count--;
            if(G->adjlist[j].count==0)      // 将入度为0的邻接点进栈
            {
                top++;
                St[top]=j;
            }
            p=p->nextarc;        //找下一个邻接点
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!