Skip to content

Commit e0547e9

Browse files
committed
update readme
1 parent 6e281b9 commit e0547e9

File tree

1 file changed

+46
-48
lines changed

1 file changed

+46
-48
lines changed

Graph/README.markdown

+46-48
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Like a tree this does not have any cycles in it (no matter where you start, ther
4242

4343
Maybe you're shrugging your shoulders and thinking, what's the big deal? Well, it turns out that graphs are an extremely useful data structure.
4444

45-
If you have some programming problem where you can represent some of your data as vertices and some of it as edges between those vertices, then you can draw your problem as a graph and use well-known graph algorithms such as [breadth-first search](../Breadth-First Search/) or [depth-first search](../Depth-First Search) to find a solution.
45+
If you have some programming problem where you can represent some of your data as vertices and some of it as edges between those vertices, then you can draw your problem as a graph and use well-known graph algorithms such as [breadth-first search](../Breadth-First Search/) or [depth-first search](../Depth-First Search) to find a solution.
4646

4747
For example, let's say you have a list of tasks where some tasks have to wait on others before they can begin. You can model this using an acyclic directed graph:
4848

@@ -110,12 +110,13 @@ We'll show you sample implementations of both adjacency list and adjacency matri
110110
The adjacency list for each vertex consists of `Edge` objects:
111111

112112
```swift
113-
public struct Edge<T where T: Equatable, T: Hashable>: Equatable {
114-
113+
public struct Edge<T>: Equatable where T: Equatable, T: Hashable {
114+
115115
public let from: Vertex<T>
116116
public let to: Vertex<T>
117117

118118
public let weight: Double?
119+
119120
}
120121
```
121122

@@ -124,7 +125,7 @@ This struct describes the "from" and "to" vertices and a weight value. Note that
124125
The `Vertex` looks like this:
125126

126127
```swift
127-
public struct Vertex<T where T: Equatable, T: Hashable>: Equatable {
128+
public struct Vertex<T>: Equatable where T: Equatable, T: Hashable {
128129

129130
public var data: T
130131
public let index: Int
@@ -147,10 +148,7 @@ We can represent it as an adjacency matrix or adjacency list. The classes implem
147148
Let's create some directed, weighted graphs, using each representation, to store the example:
148149

149150
```swift
150-
var adjacencyMatrixGraph = AdjacencyMatrixGraph<Int>()
151-
var adjacencyListGraph = AdjacencyListGraph<Int>()
152-
153-
for graph in [ adjacencyMatrixGraph, adjacencyListGraph ] {
151+
for graph in [AdjacencyMatrixGraph<Int>(), AdjacencyListGraph<Int>()] {
154152

155153
let v1 = graph.createVertex(1)
156154
let v2 = graph.createVertex(2)
@@ -163,8 +161,8 @@ for graph in [ adjacencyMatrixGraph, adjacencyListGraph ] {
163161
graph.addDirectedEdge(v3, to: v4, withWeight: 4.5)
164162
graph.addDirectedEdge(v4, to: v1, withWeight: 2.8)
165163
graph.addDirectedEdge(v2, to: v5, withWeight: 3.2)
166-
}
167164

165+
}
168166
```
169167

170168
As mentioned earlier, to create an undirected edge you need to make two directed edges. If we wanted undirected graphs, we'd call this method instead, which takes care of that work for us:
@@ -184,7 +182,7 @@ We could provide `nil` as the values for the `withWeight` parameter in either ca
184182
To maintain the adjacency list, there is a class that maps a list of edges to a vertex. The graph simply maintains an array of such objects and modifies them as necessary.
185183

186184
```swift
187-
private class EdgeList<T where T: Equatable, T: Hashable> {
185+
private class EdgeList<T> where T: Equatable, T: Hashable {
188186

189187
var vertex: Vertex<T>
190188
var edges: [Edge<T>]? = nil
@@ -193,34 +191,34 @@ private class EdgeList<T where T: Equatable, T: Hashable> {
193191
self.vertex = vertex
194192
}
195193

196-
func addEdge(edge: Edge<T>) {
194+
func addEdge(_ edge: Edge<T>) {
197195
edges?.append(edge)
198196
}
199197

200198
}
201-
```
199+
```
202200

203201
They are implemented as a class as opposed to structs so we can modify them by reference, in place, like when adding an edge to a new vertex, where the source vertex already has an edge list:
204202

205203
```swift
206-
public override func createVertex(data: T) -> Vertex<T> {
207-
// check if the vertex already exists
208-
let matchingVertices = vertices.filter() { vertex in
209-
return vertex.data == data
210-
}
211-
212-
if matchingVertices.count > 0 {
213-
return matchingVertices.last!
214-
}
215-
216-
// if the vertex doesn't exist, create a new one
217-
let vertex = Vertex(data: data, index: adjacencyList.count)
218-
adjacencyList.append(EdgeList(vertex: vertex))
219-
return vertex
204+
open override func createVertex(_ data: T) -> Vertex<T> {
205+
// check if the vertex already exists
206+
let matchingVertices = vertices.filter() { vertex in
207+
return vertex.data == data
208+
}
209+
210+
if matchingVertices.count > 0 {
211+
return matchingVertices.last!
220212
}
213+
214+
// if the vertex doesn't exist, create a new one
215+
let vertex = Vertex(data: data, index: adjacencyList.count)
216+
adjacencyList.append(EdgeList(vertex: vertex))
217+
return vertex
218+
}
221219
```
222220

223-
The adjacency list for the example looks like this:
221+
The adjacency list for the example looks like this:
224222

225223
```
226224
v1 -> [(v2: 1.0)]
@@ -238,32 +236,32 @@ We'll keep track of the adjacency matrix in a two-dimensional `[[Double?]]` arra
238236
To index into the matrix using vertices, we use the `index` property in `Vertex`, which is assigned when creating the vertex through the graph object. When creating a new vertex, the graph must resize the matrix:
239237

240238
```swift
241-
public override func createVertex(data: T) -> Vertex<T> {
242-
// check if the vertex already exists
243-
let matchingVertices = vertices.filter() { vertex in
244-
return vertex.data == data
245-
}
239+
open override func createVertex(_ data: T) -> Vertex<T> {
240+
// check if the vertex already exists
241+
let matchingVertices = vertices.filter() { vertex in
242+
return vertex.data == data
243+
}
246244

247-
if matchingVertices.count > 0 {
248-
return matchingVertices.last!
249-
}
245+
if matchingVertices.count > 0 {
246+
return matchingVertices.last!
247+
}
250248

251-
// if the vertex doesn't exist, create a new one
252-
let vertex = Vertex(data: data, index: adjacencyMatrix.count)
249+
// if the vertex doesn't exist, create a new one
250+
let vertex = Vertex(data: data, index: adjacencyMatrix.count)
253251

254-
// Expand each existing row to the right one column.
255-
for i in 0 ..< adjacencyMatrix.count {
256-
adjacencyMatrix[i].append(nil)
257-
}
252+
// Expand each existing row to the right one column.
253+
for i in 0 ..< adjacencyMatrix.count {
254+
adjacencyMatrix[i].append(nil)
255+
}
258256

259-
// Add one new row at the bottom.
260-
let newRow = [Double?](count: adjacencyMatrix.count + 1, repeatedValue: nil)
261-
adjacencyMatrix.append(newRow)
257+
// Add one new row at the bottom.
258+
let newRow = [Double?](repeating: nil, count: adjacencyMatrix.count + 1)
259+
adjacencyMatrix.append(newRow)
262260

263-
_vertices.append(vertex)
261+
_vertices.append(vertex)
264262

265-
return vertex
266-
}
263+
return vertex
264+
}
267265
```
268266

269267
Then the adjacency matrix looks like this:
@@ -273,7 +271,7 @@ Then the adjacency matrix looks like this:
273271
[nil, nil, nil, 4.5, nil] v3
274272
[2.8, nil, nil, nil, nil] v4
275273
[nil, nil, nil, nil, nil]] v5
276-
274+
277275
v1 v2 v3 v4 v5
278276

279277

0 commit comments

Comments
 (0)