跟我一起学“仓颉”算法-Tarjan算法
·
目录
一、Tarjan算法
Tarjan算法是用来求有向图的强连通分量的。Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树。搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量。
二、实现
package Algorithm.tarjan
import std.collection.*
public class TarjansAlgorithm {
// DFS遍历的索引
private var index = 0
// 记录每个顶点的访问顺序
private var indices: Array<Int64>
// 记录顶点能回溯到的最小索引
private var lowLinks: Array<Int64>
// 记录顶点是否在栈中
private var onStack: Array<Bool>
// 用于DFS的栈
private var stack: ArrayList<Int64>
// 存储所有强连通分量
private var sccs: ArrayList<ArrayList<Int64>>
public init () {
this.indices = Array<Int64>(0, item: -1)
this.lowLinks = Array<Int64>(0, item: 0)
this.onStack = Array<Bool>(0, item: false)
this.stack = ArrayList<Int64>()
this.sccs = ArrayList<ArrayList<Int64>>()
}
public func findSCCs(graph: Array<Array<Int64>>) {
let n = graph.size
this.indices = Array<Int64>(n, item: -1)
this.lowLinks = Array<Int64>(n, item: 0)
this.onStack = Array<Bool>(n, item: false)
this.stack = ArrayList<Int64>()
this.sccs = ArrayList<ArrayList<Int64>>()
for (v in 0..n) {
if (indices[v] == -1) {
dfs(v, graph)
}
}
return this.sccs
}
private func min(a: Int64, b: Int64): Int64 {
if (a > b) {
return a
} else {
return b
}
}
private func dfs(v: Int64, graph: Array<Array<Int64>>): Unit {
indices[v] = index
lowLinks[v] = index
index++
stack.append(v)
onStack[v] = true
for (w in 0..graph[v].size) {
if (indices[w] == -1) {
// 递归访问未访问的邻接顶点
dfs(w, graph);
lowLinks[v] = min(lowLinks[v], lowLinks[w])
} else if (onStack[w]) {
// 遇到在栈中的顶点,更新lowLink值
lowLinks[v] = min(lowLinks[v], indices[w])
}
}
// 如果v是强连通分量的根节点
if (lowLinks[v] == indices[v]) {
let scc = ArrayList<Int64>()
var w = 0
do {
w = stack.remove(stack.size - 1)
onStack[w] = false
scc.append(w)
} while (w != v)
sccs.append(scc)
}
}
}
测试环境
package Algorithm
import Algorithm.tarjan.*
main(): Int64 {
// 示例图
let graph = [
[1], // 0 -> 1
[2], // 1 -> 2
[0, 3], // 2 -> 0, 3
[4], // 3 -> 4
[5], // 4 -> 5
[3] // 5 -> 3
]
let tarjan = TarjansAlgorithm()
let sccs = tarjan.findSCCs(graph)
println("强连通分量:");
for (i in 0..sccs.size) {
println(sccs[i])
}
return 0
}
三、小结
本章为大家详细的介绍了仓颉数据结构与算法中Tarjan算法的内容,下一章,为大家带来Tarjan算法练习题的内容。最后,创作不易,如果大家觉得我的文章对学习仓颉数据结构与算法有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!
昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链
更多推荐

所有评论(0)