如何去理解 拓扑排序算法
查看Castle的代码,在Castle.Core中内部的数据结构采用图,排序使用的拓扑排序算法: 对于一条有向边(u,v),定义u < v;满足所有这样条件的结点序列称为拓扑序列。拓扑排序就是求一个有向图的拓扑序列的算法。 一个有向图顶点的拓扑序列不是惟一的。并不是任何有向图的顶点都可以排成拓扑序列,有环图是不能排的。 例子:比如排课问题,比如士兵排队问题等。 拓扑排序在实际生活中和算法中都有很大的应用。比如要排一下几门课程的先后次序,我们可以把课程抽象成结点,把什么课是什么课的基础抽象成边,那么该图的一个拓扑序列就是这些课的一个可行的先后次序。各种语言的编译器都用到了拓扑排序。 数学基础: 什么是拓扑排序(Topological Sort)?简单地说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。 回顾离散数学中关于偏序和全序的定义: 若集合X上的关系R是自反的、反对称的和传递的,则称只是集合X上的偏序关系。 设R是集合X上的偏序(Partial Order),如果对每个x,y∈X必有xRy或yRx,则称R是集合X上的全序关系。 直观地看,偏序指集合中仅有部分成员之间可比较,而全序指集合中全体成员之间均可比较。[例如],图7.25所示的两个有向图,图中弧(x,y)表示x≤y,则(a)表示偏序,(b)表示全序。若在(a)的有向图上人为地加一个表示v2≤v3的弧(符号“≤”表示v2领先于v3),则(a)表示的亦为全序,且这个全序称为拓扑有序(Topological Order),而由偏序定义得到拓扑有序的操作便是拓扑排序。
AOV-网及其拓扑有序序列产生的过程 (a)AOV-网;(b)输出v6之后;(c)输出v1之后;(d)输出v4之后;(e)输出v3之后;(f)输出v2之后 [思想]: 一、从有向图中选取一个没有前驱的顶点,并输出之; 二、从有向图中删去此顶点以及所有以它为尾的弧; 重复上述两步,直至图空,或者图不空但找不到无前驱的顶点为止。没有前驱 -- 入度为零,删除顶点及以它为尾的弧-- 弧头顶点的入度减1。 [人度为零的顶点拓扑排序算法]:
Status Topological Sort(ALGraph G){
//有向图G采用邻接表存储结构。
//若G无回路,则输出G的顶点的1个拓扑序列并返回OK,否则ERROR。
FindInDegree(G,indegree); //对各顶点求入度indegree[0..vernum-1]
InitStack(S);
for(i=0;i<G.vexnum; ++i)
if(!indegree[i])Push(S,i) //建零入度顶点栈,s入度为0者进栈
count=0; //对输出顶点计数
while (!StackEmpty(S)) {
Pop(S,i);
printf(i,G.vertices[i].data); ++count; //输出i号顶点并计数
for(p=G.vertices[i].firstarc;p; p=p—>nextarc) {
k=p—>adivex; //对i号顶点的每个邻接点的入度减1
if(!(--indegree[k]))Push(S,k);//若入度减为0,则入栈
}//for
}//while
if(count<G.vexnum) return ERROR; //该有向图有回路
else return OK;
}//TopologicalSort
算法 ,总的时间复杂度为O(n+e)。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- sas文本挖掘案例:如何使用SAS计算Word Mover的距离
- R语言ggplot2 对Facebook用户数据可视化分析
- 如何实现一个圆弧倒计时进度条
- R语言Kaggle泰坦尼克号性别阶级模型数据分析案例
- 以图搜图系统概述
- GitHub Pages 配置 letsencrypt 开启HTTPS
- R语言中ARMA,ARIMA(Box-Jenkins),SARIMA和ARIMAX模型用于预测时间序列数据
- 以图搜图系统工程实践
- R语言线性判别分析(LDA),二次判别分析(QDA)和正则判别分析(RDA)
- 用R语言实现神经网络预测股票实例
- R语言社区主题检测算法应用案例
- C++ vector学习笔记
- 锂电池充电慢?手把手教你制作锂电池快充充电器
- c++ cin, get学习笔记
- c++ sort 学习笔记