数据结构与算法基础 模块五
嗯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);
};