无需分层遍历的宽度优先搜索
Queue<T> queue = new LinkedList<>();
Set<T> set = new HashSet<>();
set.add(start);
queue.offer(start);
while (!queue.isEmpty()) {
T head = queue.poll();
for (T neighbor : head.neighbors) {
if (!set.contains(neighbor)) {
set.add(neighbor);
queue.offer(neighbor);
}
}
}
需要分层遍历的宽度搜先搜索
Queue<T> queue = new LinkedList<>();
Set<T> set = new HashSet<>();
set.add(start);
queue.offer(start);
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
T head = queue.poll();
for (T neighbor : head.neighbors) {
if (!set.contains(neighbor)) {
set.add(neighbor);
queue.offer(neighbor);
}
}
}
}
- set/seen 与 queue 是一对好基友,无时无刻都一起出现,往 queue 里新增一个节点,就要同时丢到 set 里。
Topological sorting
定义
在图论中,由一个有向无环图的顶点组成的序列,当且仅当满足下列条件时,称为该图的一个拓扑排序(英语:Topological sorting)。
- 每个顶点出现且只出现一次;
- 若A在序列中排在B的前面,则在图中不存在从B到A的路径。
也可以定义为:拓扑排序是对有向无环图的顶点的一种排序,它使得如果存在一条从顶点A到顶点B的路径,那么在排序中B出现在A的后面。
实际运用
拓扑排序 Topological Sorting 是一个经典的图论问题。他实际的运用中,拓扑排序可以做如下的一些事情:
- 检测编译时的循环依赖
- 制定有依赖关系的任务的执行顺序
拓扑排序不是一种排序算法
虽然名字里有 Sorting,但是相比起我们熟知的 Bubble Sort, Quick Sort 等算法,Topological Sorting 并不是一种严格意义上的 Sorting Algorithm。
确切的说,一张图的拓扑序列可以有很多个,也可能没有
。拓扑排序只需要找到其中一个
序列,无需找到所有
序列。
拓扑排序的算法是典型的宽度优先搜索算法,其大致流程如下:
- 统计所有点的入度,并初始化拓扑序列为空。
- 将所有入度为 0 的点,也就是那些没有任何
依赖
的点,放到宽度优先搜索的队列中
- 将队列中的点一个一个的释放出来,放到拓扑序列中,每次释放出某个点 A 的时候,就访问 A 的相邻点(所有A指向的点),并把这些点的入度减去 1。
- 如果发现某个点的入度被减去 1 之后变成了 0,则放入队列中。
- 直到队列为空时,算法结束,
No comments:
Post a Comment