算法与数据结构基础 - 拓扑排序(Topological Sort)
拓扑排序基础
拓扑排序用于解决有向无环图(DAG,Directed Acyclic Graph)按依赖关系排线性序列问题,直白地说解决这样的问题:有一组数据,其中一些数据依赖其他,问能否按依赖关系排序(被依赖的排在前面),或给出排序结果。
最常用解决拓扑排序问题的方法是Kahn算法,步骤可以概括为:
. 根据依赖关系,构建邻接矩阵或邻接表、入度数组 . 取入度为0的数据(即不依赖其他数据的数据),根据邻接矩阵/邻接表依次减小依赖其的数据的入度 . 判断减小后是否有新的入度为0的数据,继续进行第2步 . 直到所有数据入度为0、得到拓扑排序序列,或返回失败(存在环形依赖)
其中2、3两个步骤取入度为0数据、减小依赖其的数据的入度,过程像树的宽度优先搜索,用到类似BFS方法;以上过程用伪代码表示如下:
L ← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edge
while S is non-empty do
remove a node n from S
add n to tail of L
for each node m with an edge e from n to m do
remove edge e from the graph
if m has no other incoming edges then
insert m into S
if graph has edges then
return error (graph has at least one cycle)
else
return L (a topologically sorted order)
下面看具体例子 207. Course Schedule (有n个课程,课程间有依赖关系,问能否完成所有课程):
//207. Course Schedule
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) { //构建邻接矩阵、入度数组
vector<vector<int>> adj(numCourses);
vector<);
for(auto x:prerequisites){
adj[x.second].push_back(x.first);
indegree[x.first]++;
} //类似BFS
queue<int> q;
;i<numCourses;i++)
) q.push(i);
while(!q.empty()){
int cur=q.front();
q.pop();
numCourses--;
for(auto next:adj[cur])
) q.push(next);//新入度为0的先处理,这与正统BFS有区别
} //判断最后所有数据入度为0
;
}
以上用到邻接矩阵(adjacency matrix)表示依赖关系,时间复杂度为O(V^2),其中V为数据个数。可视化过程:这里
相关LeetCode题:
444. Sequence Reconstruction 题解
算法与数据结构基础 - 拓扑排序(Topological Sort)的更多相关文章
- LeetCode编程训练 - 拓扑排序(Topological Sort)
拓扑排序基础 拓扑排序用于解决有向无环图(DAG,Directed Acyclic Graph)按依赖关系排线性序列问题,直白地说解决这样的问题:有一组数据,其中一些数据依赖其他,问能否按依赖关系排序 ...
- 【数据结构与算法Python版学习笔记】图——拓扑排序 Topological Sort
概念 很多问题都可转化为图, 利用图算法解决 例如早餐吃薄煎饼的过程 制作松饼的难点在于知道先做哪一步.从图7-18可知,可以首先加热平底锅或者混合原材料.我们借助拓扑排序这种图算法来确定制作松饼的步 ...
- 拓扑排序 Topological Sort
2018-05-02 16:26:07 在计算机科学领域,有向图的拓扑排序或拓扑排序是其顶点的线性排序,使得对于从顶点u到顶点v的每个有向边uv,u在排序中都在v前.例如,图形的顶点可以表示要执行的任 ...
- 算法与数据结构基础 - 广度优先搜索(BFS)
BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...
- 算法与数据结构基础 - 图(Graph)
图基础 图(Graph)应用广泛,程序中可用邻接表和邻接矩阵表示图.依据不同维度,图可以分为有向图/无向图.有权图/无权图.连通图/非连通图.循环图/非循环图,有向图中的顶点具有入度/出度的概念. 面 ...
- 算法与数据结构基础 - 分治法(Divide and Conquer)
分治法基础 分治法(Divide and Conquer)顾名思义,思想核心是将问题拆分为子问题,对子问题求解.最终合并结果,分治法用伪代码表示如下: function f(input x size ...
- 算法与数据结构基础 - 贪心(Greedy)
贪心基础 贪心(Greedy)常用于解决最优问题,以期通过某种策略获得一系列局部最优解.从而求得整体最优解. 贪心从局部最优角度考虑,只适用于具备无后效性的问题,即某个状态以前的过程不影响以后的状态. ...
- 算法与数据结构基础 - 数组(Array)
数组基础 数组是最基础的数据结构,特点是O(1)时间读取任意下标元素,经常应用于排序(Sort).双指针(Two Pointers).二分查找(Binary Search).动态规划(DP)等算法.顺 ...
- 拓扑排序 (Topological Sorting)
拓扑排序(Topological Sorting) 一.拓扑排序 含义 构造AOV网络全部顶点的拓扑有序序列的运算称为拓扑排序(Topological Sorting). 在图论中,拓扑排序(Topo ...
随机推荐
- Codeforces 755B:PolandBall and Game(map+思维)
http://codeforces.com/problemset/problem/755/B 题意:A可以喊出n个字符串,B可以喊出m个字符串,如果一个字符串之前被喊过,那么它再也不能喊了,A先喊,最 ...
- tensorflow学习笔记(1)-环境配置
配置环境anaconda3+windows10+pycharm+python==3.5.2+tensorflow==1.1.4+cuda10.0+cudnn7 https://www.anaconda ...
- scrapy基础知识之 Scrapy 和 scrapy-redis的区别:
Scrapy 和 scrapy-redis的区别 Scrapy 是一个通用的爬虫框架,但是不支持分布式,Scrapy-redis是为了更方便地实现Scrapy分布式爬取,而提供了一些以redis为基础 ...
- Oracle数据库----查询
--笛卡尔集select empno,ename, 员工表.deptno, 部门表.deptno, dname from 部门表, 员工表; --添加合适的条件,可以避免笛卡尔集,从而得到正确的多表查 ...
- Oracle数据库常用脚本命令(二)
--创建学生信息表create table student( sid number(8,0), name varchar2(20), sex char(2), birthday date, addre ...
- 3. Django每日一码 之 Serializers 源码
2019-7-6 今日源码:rest-framework 序列化Serializers 序列化组件Serializers 源码分析 首先,它需要 data .many . instance,其中 in ...
- 20140117-配置文件为什么放在UI层
配置文件为什么放在UI层 (刚才写着代码突然忘了配置文件为什么要放在UI层了,只记得晓虎老师强调过.找了半天视频……) 现总结一下: 晓虎老师给出的理由,大体如下:比如一个web项目,分成三层,DAL ...
- WinForm控件之【CheckedListBox】
基本介绍 复选框列表控件,以复选框的形式将一个或多个项列表展示,从目前的情况来看应用非常有限并不广泛. 常设置属性.事件 CheckOnClick:值为true时单击项即可更改项的勾选状态,值为fal ...
- MyBatis:choose标签的用法
<!-- 4.2 choose用法 需求: 在已有的sys_user表中,除了主键id外,我们认为user_name也是唯一的, 所有的用户名都不可以重复.现在进行如下查询:当参数id有值的时候 ...
- Java编程思想:利用内部类实现的工厂模式
public class Test { public static void main(String[] args) { Factories.test(); } } /* 设计模式之禅中的工厂模式是这 ...