数据结构与算法基础 模块五

   嗯mm  现在到算法阶段了,比较多的代码,建议有时间自己在电脑上敲一下,加深理解。

  那么,现在以问题来带入:

  1、什么是拓朴排序?

对一个有向无环图进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。 
一个网应该是一个有向无环图,即不应该带有回路,因为若带有回路,则回路上的所有活动都无法进行(对于数据流来说就是死循环)。在AOV网中,若不存在回路,则所有活动可排列成一个线性序列,使得每个活动的所有前驱活动都排在该活动的前面,我们把此序列叫做拓扑序列,由AOV网构造拓扑序列的过程叫做拓扑排序(Topological sort)。

注:AOV网的拓扑序列不是唯一的,满足上述定义的任一线性序列都称作它的拓扑序列。

2、拓朴排序的实现步骤

①在有向图中选一个没有前驱的顶点并且输出

②从图中删除该顶点和所有以它为尾的弧(白话就是:删除所有和它有关的边)

③重复上述两步,直至所有顶点输出,或者当前图中不存在无前驱的顶点为止,后者代表我们的有向图是有环的,因此,也可以通过拓扑排序来判断一个图是否有环。

 3、拓朴排序的代码实现:

for (i = 0; i != this->vexnum; i++) {
        temp = this->arc[i].firstarc;
        while (temp) {
            ++this->indegree[temp->adjvex];
            temp = temp->next;
        }

    }
    for (i = 0; i != this->vexnum; i++) {
        if (!indegree[i]) {
            s.push(i);
        }
    }
    //count用于计算输出的顶点个数
    int count=0;
    while (!s.empty()) {//如果栈为空,则结束循环
        i = s.top();
        s.pop();
        cout << this->arc[i].data<<" ";
        temp = this->arc[i].firstarc;
        while (temp) {
            if (!(--this->indegree[temp->adjvex])) {
                s.push(temp->adjvex);
            }
            temp = temp->next;
        }
        ++count;
    }
    if (count == this->vexnum) {
        cout << endl;
        return true;
    } 
    return false;
}

邻接表存储的代码实现:

#include<iostream>
#include<string>
#include<stack>
using namespace std;

struct ArcNode {
    ArcNode * next;
    int adjvex;  
};
struct Vnode {
    string data;
    ArcNode * firstarc;
};

class Graph_DG {
private:
    int vexnum; //图的顶点数
    int edge;   //图的边数
    int * indegree; //每条边的入度情况
    Vnode * arc; //邻接表
public:
    Graph_DG(int, int);
    ~Graph_DG();
    bool check_edge_value(int,int);
    void createGraph();
    void print();
    bool topological_sort();
    bool topological_sort_by_dfs(); void dfs(int n,bool * & visit, stack<string> & result);
};

 

posted @ 2018-07-21 21:43  大大比巴卜  阅读(93)  评论(0编辑  收藏  举报