Created
August 25, 2019 03:04
-
-
Save davidinga/56ead53a4a5045cdbad56945a8de30b4 to your computer and use it in GitHub Desktop.
Graph data structure in Swift using Objects and Pointers with an Adjacency List.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public enum EdgeType { | |
case directed, undirected | |
} | |
public struct Edge<Element: Hashable> { | |
var source: Vertex<Element> | |
var destination: Vertex<Element> | |
var weight: Double? | |
} | |
extension Edge: Hashable { | |
public static func ==(lhs: Edge, rhs: Edge) -> Bool { | |
return lhs.source == rhs.source && lhs.destination == rhs.destination && lhs.weight == rhs.weight | |
} | |
public func hash(into hasher: inout Hasher) { | |
hasher.combine(source) | |
hasher.combine(destination) | |
hasher.combine(weight) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protocol Graphable { | |
associatedtype Element: Hashable | |
var description: CustomStringConvertible { get } | |
func createVertex(data: Element) -> Vertex<Element> | |
func add(_ type: EdgeType, from source: Vertex<Element>, to destination: Vertex<Element>, weight: Double?) | |
func weight(from source: Vertex<Element>, to destination: Vertex<Element>) -> Double? | |
func edges(from source: Vertex<Element>) -> [Edge<Element>]? | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open class GraphOP<Element: Hashable> { | |
public var adjacencyDict: [Vertex<Element>: [Edge<Element>]] = [:] | |
public init() {} | |
fileprivate func addDirectedEdge(from source: Vertex<Element>, | |
to destination: Vertex<Element>, | |
weight: Double?) { | |
let edge = Edge(source: source, destination: destination, weight: weight) | |
adjacencyDict[source]?.append(edge) | |
} | |
fileprivate func addUndirectedEdge(vertices: (Vertex<Element>, Vertex<Element>), weight: Double?) { | |
let (source, destination) = vertices | |
addDirectedEdge(from: source, to: destination, weight: weight) | |
addDirectedEdge(from: destination, to: source, weight: weight) | |
} | |
} | |
extension GraphOP: Graphable { | |
public func createVertex(data: Element) -> Vertex<Element> { | |
let vertex = Vertex(data: data) | |
if adjacencyDict[vertex] == nil { | |
adjacencyDict[vertex] = [] | |
} | |
return vertex | |
} | |
public func add(_ type: EdgeType, | |
from source: Vertex<Element>, | |
to destination: Vertex<Element>, | |
weight: Double?) { | |
switch type { | |
case .directed: | |
addDirectedEdge(from: source, to: destination, weight: weight) | |
case .undirected: | |
addUndirectedEdge(vertices: (source, destination), weight: weight) | |
} | |
} | |
public func weight(from source: Vertex<Element>, to destination: Vertex<Element>) -> Double? { | |
guard let edges = adjacencyDict[source] else { | |
return nil | |
} | |
for edge in edges { | |
if edge.destination == destination { | |
return edge.weight | |
} | |
} | |
return nil | |
} | |
public func edges(from source: Vertex<Element>) -> [Edge<Element>]? { | |
return adjacencyDict[source] | |
} | |
public var description: CustomStringConvertible { | |
var result = "" | |
for (vertex, edges) in adjacencyDict { | |
var edgeString = "" | |
for (index, edge) in edges.enumerated() { | |
if index != edges.count - 1 { | |
edgeString.append("\(edge.destination), ") | |
} else { | |
edgeString.append("\(edge.destination)") | |
} | |
} | |
result.append("\(vertex) ---> [ \(edgeString) ] \n ") | |
} | |
return result | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public struct Vertex<Element: Hashable> { | |
var data: Element | |
} | |
extension Vertex: Hashable { | |
public static func ==(lhs: Vertex, rhs: Vertex) -> Bool { | |
return lhs.data == rhs.data | |
} | |
public func hash(into hasher: inout Hasher) { | |
hasher.combine(data) | |
} | |
} | |
extension Vertex: CustomStringConvertible { | |
public var description: String { | |
return "\(data)" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment