Skip to content

Commit 99907cf

Browse files
committed
Additions to topological sort
1 parent 31db302 commit 99907cf

20 files changed

+542
-400
lines changed

README.markdown

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ Special-purpose sorts:
7474
- Bucket Sort
7575
- Counting Sort
7676
- Radix Sort
77-
- Topological Sort
77+
- [Topological Sort](Topological Sort/)
7878

7979
Bad sorting algorithms (don't use these!):
8080

Topological Sort/Graph.swift

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
public class Graph: CustomStringConvertible {
2+
public typealias Node = String
3+
4+
private(set) public var adjacencyLists: [Node : [Node]]
5+
6+
public init() {
7+
adjacencyLists = [Node : [Node]]()
8+
}
9+
10+
public func addNode(value: Node) -> Node {
11+
adjacencyLists[value] = []
12+
return value
13+
}
14+
15+
public func addEdge(fromNode from: Node, toNode to: Node) -> Bool {
16+
adjacencyLists[from]?.append(to)
17+
return adjacencyLists[from] != nil ? true : false
18+
}
19+
20+
public var description: String {
21+
return adjacencyLists.description
22+
}
23+
24+
public func adjacencyList(forNode node: Node) -> [Node]? {
25+
for (key, adjacencyList) in adjacencyLists {
26+
if key == node {
27+
return adjacencyList
28+
}
29+
}
30+
return nil
31+
}
32+
}
2.2 KB
Binary file not shown.
8.7 KB
Loading
2.77 KB
Binary file not shown.
23.5 KB
Loading

Topological Sort/README.markdown

+31-13
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,39 @@
22

33
Topological sort is an algorithm aimed at ordering a directed graph such that for each directed edge *uv* from vertex *u* to vertex *v*, *u* comes before *v*.
44

5+
In other words, a topological sort places the vertices of a directed acyclic graph on a line so that all directed edges go from left to right.
6+
7+
The graph in the following example has two possible topological sorts:
8+
9+
![Example](Images/TopologicalSort.png)
10+
511
## Where is this used?
612

7-
Let's consider that you want to learn all the algorithms present in the swift-algorithm-club, this might seem daunting at first but we can use topological sort to get things organized.
13+
Let's consider that you want to learn all the algorithms present in the Swift Algorithm Club. This might seem daunting at first but we can use topological sort to get things organized.
814

9-
For e.g. To learn the depth first search algorithm you need to know how a graph is represented. Similarly, to understand how to calculate the length of a binary tree you need to know details of how a tree is traversed. If we were to represent these in the form of a graph it would be as follows:
15+
For example, to learn the [depth-first search](../Depth-First Search/) algorithm you need to know how a [graph](../Graph/) is represented. Similarly, to understand how to calculate the length of a [binary tree](../Binary Tree/) you need to know details of how a [tree is traversed](../Tree/).
16+
17+
If we were to represent these objectives in the form of a graph it would be as follows:
1018

1119
![Example](Images/algorithm_example.png)
1220

13-
If we consider each algorithm to be a node in the graph you'll see dependancies among them i.e. to learn something you might have to know something else first. This is exactly what topological sort is used for, it will sort things out such that you know what to learn first.
21+
If we consider each algorithm to be a node in the graph you'll see dependancies among them, i.e. to learn something you might have to know something else first. This is exactly what topological sort is used for -- it will sort things out such that you know what to learn first.
1422

1523
## How does it work?
1624

17-
### Step 1: Find all nodes that have in-degree of 0
25+
**Step 1: Find all nodes that have in-degree of 0**
1826

19-
The in-degree of a node is the number of incoming edges to that node. All nodes that have no incoming edges have an in-degree of 0. These nodes are the starting points for the sort.
27+
The *in-degree* of a node is the number of incoming edges to that node. Nodes that have no incoming edges have an in-degree of 0. These nodes are the starting points for the sort.
2028

21-
If you think about it in the context of the previous example these nodes represent algorithms that don't need anything else to be learnt, hence the sort starts with them.
29+
If you think about it in the context of the previous example, these nodes represent algorithms that don't have any prerequisites; you don't need to learn anything else first, hence the sort starts with them.
2230

23-
### Step 2: Depth first search for traversal
31+
**Step 2: Depth-first search for traversal**
2432

25-
Depth first search is an algorithm that is used to traverse a graph. This algorithm traverses all the child nodes recursively and uses backtracking.
33+
Depth-first search is an algorithm that is used to traverse a graph. This algorithm traverses all the child nodes recursively and uses backtracking.
2634

27-
To know more about this algorithm please take a look at the explanation [here](https://github.com/hollance/swift-algorithm-club/tree/master/Depth-First%20Search).
35+
To find out more about depth-first search, please take a look at the [detailed explanation](../Depth-First%20Search/).
2836

29-
### Step 3: Remember all visited nodes
37+
**Step 3: Remember all visited nodes**
3038

3139
The last step of the sort is to maintain a list of all the nodes that have been visited. This is to avoid visiting the same node twice.
3240

@@ -36,16 +44,17 @@ Consider the following graph:
3644

3745
![Graph Example](Images/graph_example.png)
3846

39-
*Step 1* Nodes with 0 in-degree: **5, 7, 3**
40-
*Step 2* Depth first search for each without remembering nodes that have already been visited:
47+
**Step 1:** The nodes with 0 in-degree are: **5, 7, 3**
48+
49+
**Step 2:** Depth-first search for each starting node, without remembering nodes that have already been visited:
4150

4251
```
4352
Node 3: 3, 8, 9, 10
4453
Node 7: 7, 11, 2, 8, 9
4554
Node 5: 5, 11, 2, 9, 10
4655
```
4756

48-
*Step 3* Remember nodes already visited in each DFS.
57+
**Step 3:** Remember nodes already visited in each DFS:
4958

5059
```
5160
Node 3: 3, 8, 9, 10
@@ -54,3 +63,12 @@ Node 5: 5
5463
```
5564

5665
The final sorted order is a concatenation of the above three traversals: **3, 8, 9, 10, 7, 11, 2, 5**
66+
67+
The result of the topological sort looks like this:
68+
69+
![Result of the sort](Images/GraphResult.png)
70+
71+
TODO: I don't think this is correct! There should be no arrows going from right to left! (A valid topological order would be 3, 7, 5, 10, 8, 11, 9, 2 -- or 3, 7, 5, 8, 11, 2, 9, 10.)
72+
73+
74+
*Written for Swift Algorithm Club by Ali Hafizji*

Topological Sort/TopologicalSort/TopologicalSort/Stack.swift renamed to Topological Sort/Stack.swift

-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import Foundation
2-
31
public struct Stack<T> {
42
private var array = [T]()
53

@@ -27,13 +25,3 @@ public struct Stack<T> {
2725
return array.last
2826
}
2927
}
30-
31-
extension Stack: SequenceType {
32-
public func generate() -> AnyGenerator<T> {
33-
var curr = self
34-
return anyGenerator {
35-
_ -> T? in
36-
return curr.pop()
37-
}
38-
}
39-
}

0 commit comments

Comments
 (0)