Skip to content

Commit 6810167

Browse files
committed
Improve topologicalSort performance
1 parent 399c17c commit 6810167

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

Sources/SwiftGraph/Sort.swift

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,27 @@ public extension Graph {
2929
/// - returns: the sorted vertices, or nil if the graph cannot be sorted due to not being a DAG
3030
func topologicalSort() -> [V]? {
3131
var sortedVertices = [V]()
32-
let tsNodes = vertices.map{ TSNode<V>(vertex: $0, color: .white) }
32+
let rangeOfVertices = 0..<vertexCount
33+
let tsNodes = rangeOfVertices.map { TSNode(index: $0, color: .white) }
3334
var notDAG = false
35+
36+
// Determine vertex neighbors in advance, so we have to do it once for each node.
37+
var neighbors: [Set<Int>] = rangeOfVertices.map({ index in
38+
Set(edges[index].map({ $0.v }))
39+
})
3440

35-
func visit(_ node: TSNode<V>) {
41+
func visit(_ node: TSNode) {
3642
guard node.color != .gray else {
3743
notDAG = true
3844
return
3945
}
4046
if node.color == .white {
4147
node.color = .gray
42-
for inode in tsNodes where (neighborsForVertex(node.vertex)?.contains(inode.vertex))! {
48+
for inode in tsNodes where neighbors[node.index].contains(inode.index) {
4349
visit(inode)
4450
}
4551
node.color = .black
46-
sortedVertices.insert(node.vertex, at: 0)
52+
sortedVertices.insert(vertices[node.index], at: 0)
4753
}
4854
}
4955

@@ -71,12 +77,12 @@ public extension Graph {
7177

7278
fileprivate enum TSColor { case black, gray, white }
7379

74-
fileprivate class TSNode<V> {
75-
fileprivate let vertex: V
80+
fileprivate class TSNode {
81+
fileprivate let index: Int
7682
fileprivate var color: TSColor
77-
78-
init(vertex: V, color: TSColor) {
79-
self.vertex = vertex
83+
84+
init(index: Int, color: TSColor) {
85+
self.index = index
8086
self.color = color
8187
}
8288
}

0 commit comments

Comments
 (0)