tsort - 拓扑排序
tsort - 拓扑排序
本文链接:http://codingstandards.iteye.com/blog/834572 (转载请注明出处)
用途说明
tsort命令通常用于解决一种逻辑问题,即必须通过观察到的部分次序预测出整个次序。tsort命令可以对保存在文本文件中的数据进行拓扑排序,只要你按照一定的规则把数据写在文本文件中,然后使用tsort命令进行排序。
拓扑排序是对有向无环图的一种排序。表示了顶点按边的方向出现的先后顺序。如果有环,则无法表示两个顶点的先后顺序。
在现实生活中,也会有不少应用例子,比如学校课程布置图,要先修完一些基础课,才可以继续修专业课。
在软件开发中,比如多个模块之间的依赖关系、编译顺序,函数之间的调用关系等。
在项目管理中,各个任务之间的先后次序,某些任务完成之后才能进行另外的任务等。
一个简单的求拓扑排序的算法:首先要找到任意入度为0的一个顶点,删除它及所有相邻的边,再找入度为0的顶点,以此类推,直到删除所有顶点。顶点的删除顺序即为拓扑排序。
常用参数
无。
使用示例
示例一 来自info tsort的例子:根据部分顺序预测整体顺序
tsort输入数据的规则,把每两个数据作为一组,这两个数据就表明了一种部分顺序,每个数据之间以空白分隔,tsort处理结果就是根据这些部分顺序来推导出整体顺序来(`tsort' reads its input as pairs of strings, separated by blanks, indicating a partial ordering. The output is a total ordering that corresponds to the given partial ordering.)。比如下面的数据,从上到下,a b是一组,c d又是一组,e f是一组,b c是一组,d e是一组。
[root@new55 ~]# tsort <<EOF
> a b c
> d
> e f
> b c d e
> EOF
a
b
c
d
e
f
[root@new55 ~]#
示例二 来自info tsort的例子:函数之间的调用关系
下面例子中的call-graph文件中保存了一个C程序中函数之间的调用关系(依赖关系),这个程序看起来像是tail命令的实现,文件第一行表明 main函数调用了 parse_options函数,第二行表明 main函数调用了tail_file函数,以此类推。后面使用tsort排序再采用tac逆序排列得到的结果就是在C文件中各个函数的顺序,比如先定义dump_remainder函数,再定义start_lines函数等。
[root@new55 ~]# cat call-graph
main parse_options
main tail_file
main tail_forever
tail_file pretty_name
tail_file write_header
tail_file tail
tail_forever recheck
tail_forever pretty_name
tail_forever write_header
tail_forever dump_remainder
tail tail_lines
tail tail_bytes
tail_lines start_lines
tail_lines dump_remainder
tail_lines file_lines
tail_lines pipe_lines
tail_bytes xlseek
tail_bytes start_bytes
tail_bytes dump_remainder
tail_bytes pipe_bytes
file_lines dump_remainder
recheck pretty_name
[root@new55 ~]# tsort call-graph | tac
dump_remainder
start_lines
file_lines
pipe_lines
xlseek
start_bytes
pipe_bytes
tail_lines
tail_bytes
pretty_name
write_header
tail
recheck
parse_options
tail_file
tail_forever
main
[root@new55 ~]#
示例三 比较sort和tsort
下面的happybirthday.txt中,Happy Birthday是一组,to You!是一组,Dear Tux!是一组,每组都表明了一种顺序,因为各个组之间的数据关联性不大,所以tsort的输出结果只是拓扑排序的一种可能结果而已。这个例子来自ibm的一篇文章,对于 tsort 的使用来说,这并非一个非常有用的演示,只是举例说明了这两个命令输出的不同。
[root@new55 ~]# cat happybirthday.txt
Happy Birthday to You!
Happy Birthday to You!
Happy Birthday Dear Tux!
Happy Birthday to You!
[root@new55 ~]# sort happybirthday.txt
Happy Birthday Dear Tux!
Happy Birthday to You!
Happy Birthday to You!
Happy Birthday to You!
[root@new55 ~]# tsort happybirthday.txt
Dear
Happy
to
Tux!
Birthday
You!
[root@new55 ~]#
实例四 根据jquery/js组件的依赖关系确定加载顺序
下面的例子中js.txt中保存了js脚本之间的依赖关系,每行的第一个文件依赖于后面的一个或多个文件。但这种格式显然不符合tsort的输入数据要求,因此编写脚本deps.sh把它转换成tsort要求的格式,即每行两个文件,前一个文件依赖于后一个文件。转换之后用tsort拓扑排序,然后用tac逆序输出之后就得到了这些js文件的正确加载顺序。
[root@new55 ~]# cat js.txt
pagination.js jquery.js
xheditor.js jquery.js
AreaData.js jquery.js
jquery.progressbar.js jquery.js
jquery.cookie.js jquery.js
hotkeys.js jquery.js
jsTree.js jquery.js
jquery.contextMenu.js jquery.js
jquery.messager.js jquery.js
jquery.jtemplates.js jquery.js
jquery.sound.js jquery.js
jquery.bgiframe.js jquery.js
jquery.ui.core.js jquery.js
jquery.ui.widget.js jquery.ui.core.js jquery.bgiframe.js
jquery.ui.mouse.js jquery.ui.core.js jquery.ui.widget.js
jquery.ui.draggable.js jquery.ui.core.js jquery.ui.mouse.js jquery.ui.widget.js
jquery.ui.position.js jquery.ui.core.js jquery.js jquery.bgiframe.js
jquery.ui.resizable.js jquery.ui.core.js jquery.ui.mouse.js jquery.ui.widget.js
jquery.ui.button.js jquery.ui.widget.js jquery.js
jquery.metadata.js jquery.js
jquery.msgc.js jquery.js json2.js
ajaxfileupload.js jquery.js
jquery.ui.dialog.js jquery.bgiframe.js jquery.ui.core.js jquery.ui.widget.js jquery.ui.button.js jquery.ui.draggable.js jquery.ui.mouse.js jquery.ui.position.js jquery.ui.resizable.js
[root@new55 ~]# cat deps.sh
#!/bin/sh
# 输入数据格式:每行的第一个文件依赖于本行后面其他的文件
# 输出数据格式:符合tsort要求的数据格式,每行两个文件,前面一个依赖于后面那个。
while read js deps
do
for dep in $deps
do
echo $js $dep
done
done
[root@new55 ~]# dos2unix js.txt
dos2unix: converting file js.txt to UNIX format ...
[root@new55 ~]# cat js.txt | ./deps.sh | tsort | tac
jquery.js
jquery.ui.core.js
jquery.bgiframe.js
jquery.ui.widget.js
jquery.ui.mouse.js
json2.js
xheditor.js
pagination.js
jsTree.js
jquery.ui.resizable.js
jquery.ui.position.js
jquery.ui.draggable.js
jquery.ui.button.js
jquery.sound.js
jquery.progressbar.js
jquery.msgc.js
jquery.metadata.js
jquery.messager.js
jquery.jtemplates.js
jquery.cookie.js
jquery.contextMenu.js
hotkeys.js
ajaxfileupload.js
AreaData.js
[root@new55 ~]#
问题思考
相关资料
【1】IBM developerworks 技巧: 用 sort 和 tsort 对文件进行排序
【2】维基百科 tsort (Unix)
【3】百度百科 拓扑排序
【4】gqf2008 图论算法——拓扑排序
【5】熟能生巧 拓扑排序
【6】维基百科 拓扑排序
【7】景高专 拓扑排序演示动画
tsort - 拓扑排序的更多相关文章
- hdu3231 (三重拓扑排序) 2009 Asia Wuhan Regional Contest Hosted by Wuhan University
这道题算是我拓扑排序入门的收棺题了,卡了我好几天,期间分别犯了超时,内存溢出,理解WA,细节WA,格式WA…… 题目的意思大概是在一个三维坐标系中,有一大堆矩形,这些矩形的每条棱都与坐标轴平行. 这些 ...
- bzoj1880: [Sdoi2009]Elaxia的路线(spfa,拓扑排序最长路)
1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1944 Solved: 759[Submit][St ...
- 算法与数据结构(七) AOV网的拓扑排序
今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...
- 有向无环图的应用—AOV网 和 拓扑排序
有向无环图:无环的有向图,简称 DAG (Directed Acycline Graph) 图. 一个有向图的生成树是一个有向树,一个非连通有向图的若干强连通分量生成若干有向树,这些有向数形成生成森林 ...
- 【BZOJ-2938】病毒 Trie图 + 拓扑排序
2938: [Poi2000]病毒 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 609 Solved: 318[Submit][Status][Di ...
- BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)
题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...
- 图——拓扑排序(uva10305)
John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task i ...
- Java排序算法——拓扑排序
package graph; import java.util.LinkedList; import java.util.Queue; import thinkinjava.net.mindview. ...
- poj 3687(拓扑排序)
http://poj.org/problem?id=3687 题意:有一些球他们都有各自的重量,而且每个球的重量都不相同,现在,要给这些球贴标签.如果这些球没有限定条件说是哪个比哪个轻的话,那么默认的 ...
随机推荐
- centos7 关闭默认firewalld,开启iptables
编者按: 对于使用了centos6系列系统N年的运维来说,在使用centos7的时候难免会遇到各种不适应.比如防火墙问题.本文主要记录怎么关闭默认的firewalld防火墙,重新启用iptables. ...
- 黑马程序员_java基础笔记(03)...面向对象
—————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流!—————————— 1:面向对象的概念,2 : 类和对象的关系,3 : 封装,4 : 构造函数,5 : ...
- 基于五阶段流水线的RISC-V CPU模拟器实现
RISC-V是源自Berkeley的开源体系结构和指令集标准.这个模拟器实现的是RISC-V Specification 2.2中所规定RV64I指令集,基于标准的五阶段流水线,并且实现了分支预测模块 ...
- idea导入或打开项目配置问题
learn项目遇到问题: 1.IntelliJ Idea编译报错:请使用 -source 7 或更高版本以启用 diamond 运算符 file - project structure或者直接快捷键: ...
- kube-ui安装
kube-ui是k8s提供的web管理界面,可以展示节点的内存.CPU.磁盘.Pod.RC.SVC等信息. 1.编辑kube-dashboard-rc.yml定义文件[root@kubernetes- ...
- python issubclass 和 isinstance函数
Python issubclass() 函数 issubclass() 方法用于判断参数 class 是否是类型参数 classinfo 的子类. 语法: issubclass(class, clas ...
- 「JSOI2018」战争
「JSOI2018」战争 解题思路 我们需要每次求给一个凸包加上一个向量后是否与另外一个凸包相交,也就是说是否存在 \[ b\in B,(b+w)\in A \] 这里 \(A, B\) 表示凸包内部 ...
- 认识javascript中的作用域和上下文
javascript中的作用域(scope)和上下文(context)是这门语言的独到之处,这部分归功于他们带来的灵活性.每个函数有不同的变量上下文和作用域.这些概念是javascript中一些强大的 ...
- LR监控Apache资源
前提本文使用的是lampp环境下自带的Apache服务 步骤1.修改Apache中Httpd.conf文件,添加如下代码:文件位置为:/opt/lampp/etc/httpd.conf,如下图: &l ...
- ROS知识(14)----局部避障的动态窗口算法(DWA)及其调试的方法
Dynamic Window Approach(DWA)是重要的局部轨迹规划算法,ROS中使用了DWA算法获得了很好的局部路径规划的效果.具体的教程可参考官方的导航调试资料Navigation Tun ...