拓扑排序


有向无环图的拓扑排序是顶点的线性排序。对于有向图的每条边 U-V,顶点 u 将在排序中排在顶点 v 之前。

如我们所知,源顶点排在目标顶点的后面,因此我们需要使用一个栈来存储先前的元素。完成所有节点后,我们可以简单地从堆栈中显示它们。

输入输出

Input:
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 1 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 0 0 0

Output:
Nodes after topological sorted order: 5 4 2 3 1 0

算法

topoSort(u, visited, stack)

输入 − 开始顶点 u、用于跟踪已访问或未访问的节点的数组。用于存储节点的堆栈。
输出 − 在栈中按拓扑顺序对顶点进行排序。

Begin
   mark u as visited
   for all vertices v which is adjacent with u, do
      if v is not visited, then
         topoSort(c, visited, stack)
   done

   push u into a stack
End

performTopologicalSorting(Graph)

输入 − 给定的有向无环图。
输出 − 节点序列。

Begin
   initially mark all nodes as unvisited
   for all nodes v of the graph, do
      if v is not visited, then
         topoSort(i, visited, stack)
   done
   pop and print all elements from the stack
End.

示例

#include<iostream>
#include<stack>
#define NODE 6
using namespace std;

int graph[NODE][NODE] = {
   {0, 0, 0, 0, 0, 0},
   {0, 0, 0, 0, 0, 0},
   {0, 0, 0, 1, 0, 0},
   {0, 1, 0, 0, 0, 0},
   {1, 1, 0, 0, 0, 0},
   {1, 0, 1, 0, 0, 0}
};

void topoSort(int u, bool visited[], stack<int>&stk) {
   visited[u] = true;                //set as the node v is visited

   for(int v = 0; v<NODE; v++) {
      if(graph[u][v]) {             //for allvertices v adjacent to u
         if(!visited[v])
            topoSort(v, visited, stk);
      }
   }
   stk.push(u);     //push starting vertex into the stack
}

void performTopologicalSort() {
   stack<int> stk;
   bool vis[NODE];

   for(int i = 0; i<NODE; i++)
      vis[i] = false;     //initially all nodes are unvisited

   for(int i = 0; i<NODE; i++)
      if(!vis[i])     //when node is not visited
         topoSort(i, vis, stk);

   while(!stk.empty()) {
      cout << stk.top() << " ";
      stk.pop();
   }
}

main() {
   cout << "Nodes after topological sorted order: ";
   performTopologicalSort();
}

输出

Nodes after topological sorted order: 5 4 2 3 1 0

更新于:2020 年 6 月 16 日

6 千次 + 浏览

开启您的 职业

通过完成课程获得认证

开始
广告
© . All rights reserved.