http://www.lintcode.com/zh-cn/problem/topological-sorting/#

给定一个有向图,图节点的拓扑排序被定义为:

  • 对于每条有向边A--> B,则A必须排在B之前
  • 拓扑排序的第一个节点可以是任何在图中没有其他节点指向它的节点

找到给定图的任一拓扑排序

solution

Topological Sorting

Topological sorting for Directed Acyclic Graph (DAG) is a linear ordering of vertices such that for every directed edge uv, vertex u comes before v in the ordering. Topological Sorting for a graph is not possible if the graph is not a DAG.

For example, a topological sorting of the following graph is “5 4 2 3 1 0″. There can be more than one topological sorting for a graph. For example, another topological sorting of the following graph is “4 5 2 3 1 0″. The first vertex in topological sorting is always a vertex with in-degree as 0 (a vertex with no in-coming edges).

Topological Sorting vs Depth First Traversal (DFS):
In DFS, we print a vertex and then recursively call DFS for its adjacent vertices. In topological sorting, we need to print a vertex before its adjacent vertices. For example, in the given graph, the vertex ‘5’ should be printed before vertex ‘0’, but unlike DFS, the vertex ‘4’ should also be printed before vertex ‘0’. So Topological sorting is different from DFS. For example, a DFS of the above graph is “5 2 3 1 0 4″, but it is not a topological sorting

Algorithm to find Topological Sorting:
We recommend to first see implementation of DFS here. We can modify DFSto find Topological Sorting of a graph. In DFS, we start from a vertex, we first print it and then recursively call DFS for its adjacent vertices. In topological sorting, we use a temporary stack. We don’t print the vertex immediately, we first recursively call topological sorting for all its adjacent vertices, then push it to a stack. Finally, print contents of stack. Note that a vertex is pushed to stack only when all of its adjacent vertices (and their adjacent vertices and so on) are already in stack.

引用自 http://www.geeksforgeeks.org/topological-sorting/

如果仅仅只是对DAG进行DFS,那么针对某一起始点(例如上图中的5)开始的DFS确实可以满足Topological sorting,但是当对该点DFS范围以外的其他点(例如上图中的4)再进行DFS时,很可能会出现不满足Topological sorting的情况。例如上图中,在4指向1的清凉下。那如何解决?

利用栈后进先出的性质,我们可以依次递归的将每一个vertex的adjacent vertices先入栈,vertex最后入栈,这样vertices的出栈顺序即满足Topological sorting,代码如下:

// Author: Jian-xin Zhou

/**
* Definition for Directed graph.
* struct DirectedGraphNode {
* int label;
* vector<DirectedGraphNode *> neighbors;
* DirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
/**
* @param graph: A list of Directed graph node
* @return: Any topological order for the given graph.
*/
vector<DirectedGraphNode*> topSort(vector<DirectedGraphNode*> graph) {
// write your code here
unordered_set<DirectedGraphNode*> unique;
stack<DirectedGraphNode*> st;
topologicalSort(graph, unique, st); vector<DirectedGraphNode*> ret;
while (!st.empty()) {
ret.push_back(st.top());
st.pop();
} return ret;
} private:
void topologicalSortUtil(DirectedGraphNode *node,
unordered_set<DirectedGraphNode*> &unique,
stack<DirectedGraphNode*> &st) {
// 处理 neighbors
for (const auto &nodePointer : node->neighbors) {
if (unique.count(nodePointer) == 0) {
unique.insert(nodePointer);
topologicalSortUtil(nodePointer, unique, st);
}
} // 处理完 neighbors ,自身入栈
st.push(node);
} void topologicalSort(vector<DirectedGraphNode*> graph,
unordered_set<DirectedGraphNode*> &unique,
stack<DirectedGraphNode*> &st) {
for (const auto &node : graph) {
if (unique.count(node) == 0) {
unique.insert(node);
topologicalSortUtil(node, unique, st);
}
}
}
};

最新文章

  1. Redis初识
  2. Shell文件权限和脚本执行
  3. WinServer 2008 远程桌面连接设置
  4. MFC中无边框窗口的拖动
  5. Lua 之数据结构
  6. Java中的线程
  7. Spring MVC 之输入验证(六)
  8. 1090. Highest Price in Supply Chain (25)
  9. tdx api z
  10. 带你了解世界最先进的手势识别技术 -- 微软,凌感,Leap...
  11. ecshop加广告出现广告位的宽度值必须在1到1024之间的解决方法
  12. PHP 删除非法UTF-8字符
  13. 【Android Developers Training】 24. 保存键值对
  14. 从头编写 asp.net core 2.0 web api 基础框架 (3)
  15. [Swift]LeetCode273. 整数转换英文表示 | Integer to English Words
  16. scrapy Mongodb 储存
  17. linux(centos) tomcat设置开机启动
  18. Windows 下面 redis 发布为服务的官方方法
  19. C# 值传参和引用传参
  20. 20155312 2016-2017-2 《Java程序设计》第九周学习总结

热门文章

  1. python——简单爬虫
  2. 需求文件requirements.txt的创建及使用
  3. pselect 函数
  4. mysql 压缩版安装
  5. javascript对象bind()方法兼容处理
  6. jQuery之JSP加载JS文件不起作用的有效解决方法
  7. TensorFlow安装时错误CondaValueError: prefix already exists: G:\softs\Anaconda\envs\tensorflow
  8. Centos上安装phpmyadmin
  9. libmysqlclient version
  10. Rest架构风格的实践(使用通用Mapper技术)