拓扑排序C++实现

一.定义

对一个有向无环图(Directed Acyclic Graph, DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前。

通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列

注意:

1)只有有向无环图才存在拓扑序列;

2)对于一个DAG,可能存在多个拓扑序列;

如:

《拓扑排序C++实现》该DAG的拓扑序列为 A B C D 或者 A C B D

 《拓扑排序C++实现》   而此有向图是不存在拓扑序列的,因为图中存在环路

二.拓扑序列算法思想

(1)从有向图中选取一个没有前驱(即入度为0)的顶点,并输出之;

(2)从有向图中删去此顶点以及所有以它为尾的弧;

重复上述两步,直至图空,或者图不空但找不到无前驱的顶点为止。


三.代码实现

采用邻接表实现,邻接表表示请见下图。

《拓扑排序C++实现》

#include <iostream>
#include <fstream>
#include <stack>
#include <cstring>
using namespace std;

#define MAX_VERTEX_NUM 26

typedef struct ArcNode{
        int adjvex;
        struct ArcNode *nextarc;
        ArcNode(){nextarc=NULL;}
}ArcNode;

typedef struct VNode{
        int data;
        ArcNode *firstarc;
        VNode(){firstarc=NULL;}
}VNode,AdjList[MAX_VERTEX_NUM];

typedef struct{
        AdjList vertices;
        int vexnum,arcnum;
}ALGraph;

bool TopologicalSort(ALGraph G,int *indegree)
{
        stack<int> s;

        int i,k;
        for(i=1;i<G.vexnum+1;i++)
        {
                if(!indegree[i])
                        s.push(i);
        }

        int count=0;
        ArcNode *p;
        while(!s.empty())
        {
                i = s.top();
                s.pop();
                cout<<G.vertices[i].data<<"->";
                count++;
                for(p=G.vertices[i].firstarc;p;p=p->nextarc)
                {
                        k = p->adjvex;
                        indegree[k]--;
                        if(!indegree[k])
                                s.push(k);
                }
        }

        if(count<G.vexnum)
                return false;

        return true;
}

int main()
{
        int i;
        ALGraph g;
        cout<<"载入图中..."<<endl;
        ifstream fin("in.txt");
        fin>>g.vexnum>>g.arcnum;
        for(i=1;i<g.vexnum+1;i++)
                g.vertices[i].data = i;

        int b,e;
        ArcNode *p;
        int *indegree = new int[g.vexnum+1];
        //注意 int *a=new int(n);  申请一个整型变量空间,赋初值为n,并定义一个整型指针a指向该地址空间
        //int *indegree=(int *)malloc(sizeof(int)*(g.vexnum+1));
        memset(indegree,0,sizeof(int)*(g.vexnum+1));
        for(i=1;i<g.arcnum+1;i++)
        {
                fin>>b>>e;
                cout<<"第"<<i<<"条边:"<<b<<"->"<<e<<endl;

                p = new ArcNode();
                p->adjvex = e;
                p->nextarc = g.vertices[b].firstarc;
                g.vertices[b].firstarc = p;
                indegree[e]++;
        }

        if(TopologicalSort(g,indegree))
                cout<<"正常完成!"<<endl;
        else
                cout<<"该有向图有回路!"<<endl;

        return 0;
}

两组测试数据:

1)有环

4 4
1 2
2 3
3 4
4 2

2)无环

12 16
1 2
1 3
2 3
1 4
3 5
4 5
11 6
5 7
3 7
3 8
6 8
9 10
9 11
9 12
10 12
1 12

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/ywcpig/article/details/52599867
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞