拓扑排序是图论中的一种常见排序的算法(当且仅当为有向图成立)。图论中顶点与顶点存在依赖关系,比如A—>B,解释为A与B存在依赖关系,A在B之前先发生。有时候我们想了解图中各顶点的发生顺序,拓扑排序便解决了此问题。
拓扑排序的思想:我们检查所有顶点的入度,当该顶点的入度为0时,便将其压入队列中(为什么要用队列呢?因为队列具有先进先出的思想啊~),当队列不为空时,便删除其首元素,然后降低与其邻接顶点的入度,当期顶点为0时,就将其压入队列中。
现在我们就以下面的图来实现拓扑排序:
完整代码如下:
#include<iostream>
#include<list>
#include<queue>
#include<memory>
struct Vertex {
size_t* indegree; //存储每个顶点的入读
size_t vertexnumber; //图中顶点个数
};
class Graph {
public:
Graph(const size_t _vertexnumber) :vertex(std::make_unique<Vertex>()), adjacency_table(new std::list<size_t>[_vertexnumber]), indq(new std::queue<size_t>()) {
vertex->indegree = new size_t[_vertexnumber]();
vertex->vertexnumber = _vertexnumber;
}
~Graph() {
if (vertex->indegree && adjacency_table && indq) {
delete[] vertex->indegree;
delete[] adjacency_table;
delete indq;
}
else
throw std::out_of_range("Out of MemorySpace!!");
}
void AddEdge(const size_t v, const size_t w);
void TopologicalSort();
private:
std::unique_ptr<Vertex>vertex;
std::list<size_t>*adjacency_table; //邻接表
std::queue<size_t>*indq;
};
void Graph::AddEdge(const size_t v, const size_t w) {
adjacency_table[v].push_back(w);
vertex->indegree[w] += 1;
}
void Graph::TopologicalSort() {
for (int i = 0; i < vertex->vertexnumber; ++i) {
if (vertex->indegree[i] == 0)
indq->push(i);
}
size_t count = 0;
while (!indq->empty()) {
auto v = indq->front();
indq->pop();
std::cout << v << std::endl;
++count;
std::list<size_t>::const_iterator beg = adjacency_table[v].begin();
while (beg != adjacency_table[v].end()) {
if (!(--vertex->indegree[*beg]))
indq->push(*beg);
++beg;
}
}
if (count < vertex->vertexnumber) //检查图中是否存在环路
std::cout << "There is a loop in the picture!!" << std::endl;
else
return;
}
int main(void)
{
const size_t indegreenumber = 7;
Graph graph(indegreenumber);
graph.AddEdge(0, 1);
graph.AddEdge(0, 2);
graph.AddEdge(0, 3);
graph.AddEdge(1, 3);
graph.AddEdge(1, 4);
graph.AddEdge(2, 5);
graph.AddEdge(3, 2);
graph.AddEdge(3, 5);
graph.AddEdge(3, 6);
graph.AddEdge(3, 4);
graph.AddEdge(4, 6);
graph.AddEdge(6, 5);
graph.TopologicalSort();
std::system("pause");
}
参考: 《数据结构与算法分析C语言描述》
参考:https://blog.csdn.net/lisong694767315/article/details/45543451