【数据结构】拓扑排序

来源:互联网 发布:淘宝买家会员等级划分 编辑:程序博客网 时间:2024/06/05 06:32

设G=(V, E)是一个具有n个顶点的有向图,V中的顶点序列v0,v1,v2,…,vn-1如果满足下列条件:若从vi到vj有一条路径,则在顶点序列中顶点vi必定在vj之前,这样的序列称为拓扑序列。对一个有向图构造拓扑序列的过程称为拓扑排序(topological sort)。

显然,每一个可以构造出不止一个拓扑序列。

拓扑排序的步骤如下:1、在有向图中选一个没有前驱的顶点并输出;2、从图中删除该顶点和所有以它为尾的弧。
重复以上两个步骤,直至全部顶点均已输出,或者当前图中不存在无前驱的顶点为止。后一种情况说明有向图中存在环。
下图说明拓扑排序的过程。假设存在多个结点没有前驱,则任选一个顶点均可。

这里写图片描述

拓扑排序的实现:

首先求所有顶点的入度,然后在执行拓扑排序的过程中,当某个顶点的入度为零(即没有前驱顶点)时,就将此顶点输出,同时将该顶点的所有后继顶点的入度减1,以达到删除顶点和以它为尾的弧的操作。为了避免重复检测入度为零的顶点,使用栈存放入度为零的顶点。

const int MaxVertexNum = 20;struct DNENode {    int adjvex;    int weight;    struct DNENode * next;};template<typename T>struct VNode {    T data;    DNENode * firstedge;};template <typename T>class DNALGraph{public:    DNALGraph();    ~DNALGraph();    int LocateVex(T u);                 //返回顶点u在图中的位置    void FindInDegree(int indegree[]);  //求所有顶点的入度    bool TopoSort();                    //拓扑排序private:    VNode<T> vertices[MaxVertexNum];    //顶点集    int vexnum;                         //顶点数    int arcnum;                         //边数};template<typename T>void DNALGraph<T>::FindInDegree(int indegree[]) {    int i;    DNENode *p;    for (i = 0; i < vexnum; ++i)        indegree[i] = 0;    for (i = 0; i < vexnum; ++i) {        p = vertices[i].firstedge;        while (p) {            indegree[p->adjvex]++;            p = p->next;        }    }}#include "stack"template <typename T>bool DNALGraph<T>::TopoSort() {    int i, k, count = 0;    int indegree[MaxVertexNum];     //入度数组,存放各顶点当前入度数    int a[MaxVertexNum];    stack<int> s(a, 0);    DNENode *p;    FindInDegree(indegree);         //对各顶点求入度    for (i = 0; i < vexnum; ++i)    //将入度为0的顶点进栈        if (!indegree[i])            s.push(i);    while (!s.empty()) {        i = s.top();                //出栈并赋值        s.pop();        cout << vertices[i].data << ' ';    //输出i号顶点        ++count;        //对第i号顶点的每个邻接顶点进行处理        for (p = vertices[i].firstedge; p; p = p->next) {            k = p->adjvex;              //其序号为k            if (!(--indegree[k]))       //k的入度减1,若减为0,则将其入栈                s.push(k);        }    }    if (count < vexnum) {       //零入度点栈已空时还有顶点没输出的情况        cout << "There is a loop in the graph.\n";        return false;    } else {        cout << " is a topological sort.\n";        return true;    }}
1 0
原创粉丝点击