forked from kodecocodes/swift-algorithm-club
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Graph.swift
106 lines (82 loc) · 2.25 KB
/
Graph.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// MARK: - Edge
open class Edge: Equatable {
open var neighbor: Node
public init(neighbor: Node) {
self.neighbor = neighbor
}
}
public func == (lhs: Edge, rhs: Edge) -> Bool {
return lhs.neighbor == rhs.neighbor
}
// MARK: - Node
open class Node: CustomStringConvertible, Equatable {
open var neighbors: [Edge]
open fileprivate(set) var label: String
open var distance: Int?
open var visited: Bool
public init(label: String) {
self.label = label
neighbors = []
visited = false
}
open var description: String {
if let distance = distance {
return "Node(label: \(label), distance: \(distance))"
}
return "Node(label: \(label), distance: infinity)"
}
open var hasDistance: Bool {
return distance != nil
}
open func remove(_ edge: Edge) {
neighbors.remove(at: neighbors.index { $0 === edge }!)
}
}
public func == (lhs: Node, rhs: Node) -> Bool {
return lhs.label == rhs.label && lhs.neighbors == rhs.neighbors
}
// MARK: - Graph
open class Graph: CustomStringConvertible, Equatable {
open fileprivate(set) var nodes: [Node]
public init() {
self.nodes = []
}
open func addNode(_ label: String) -> Node {
let node = Node(label: label)
nodes.append(node)
return node
}
open func addEdge(_ source: Node, neighbor: Node) {
let edge = Edge(neighbor: neighbor)
source.neighbors.append(edge)
}
open var description: String {
var description = ""
for node in nodes {
if !node.neighbors.isEmpty {
description += "[node: \(node.label) edges: \(node.neighbors.map { $0.neighbor.label})]"
}
}
return description
}
open func findNodeWithLabel(_ label: String) -> Node {
return nodes.filter { $0.label == label }.first!
}
open func duplicate() -> Graph {
let duplicated = Graph()
for node in nodes {
_ = duplicated.addNode(node.label)
}
for node in nodes {
for edge in node.neighbors {
let source = duplicated.findNodeWithLabel(node.label)
let neighbour = duplicated.findNodeWithLabel(edge.neighbor.label)
duplicated.addEdge(source, neighbor: neighbour)
}
}
return duplicated
}
}
public func == (lhs: Graph, rhs: Graph) -> Bool {
return lhs.nodes == rhs.nodes
}