Skip to content

Commit 243f925

Browse files
committed
Improve explanation of DFS
1 parent 1f5c20e commit 243f925

File tree

11 files changed

+33
-11
lines changed

11 files changed

+33
-11
lines changed

Breadth-First Search/README.markdown

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Breadth-first search (BFS) is an algorithm for traversing or searching [tree](../Tree/) or [graph](../Graph/) data structures. It starts at a source node and explores the immediate neighbor nodes first, before moving to the next level neighbors.
44

5+
Breadth-first search can be used on both directed and undirected graphs.
6+
57
## Animated example
68

79
Here's how breadth-first search works on a graph:
@@ -83,8 +85,6 @@ The parent of a node is the one that "discovered" that node. The root of the tre
8385

8486
For an unweighted graph, this tree defines a shortest path from the starting node to every other node in the tree. So breadth-first search is one way to find the shortest path between two nodes in a graph.
8587

86-
Breadth-first search can be used on directed and undirected graphs.
87-
8888
## The code
8989

9090
Simple implementation of breadth-first search using a queue:

Depth-First Search/DepthFirstSearch.playground/Pages/Simple Example.xcplaygroundpage/Contents.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ graph.addEdge(nodeB, neighbor: nodeE)
3030
graph.addEdge(nodeC, neighbor: nodeF)
3131
graph.addEdge(nodeC, neighbor: nodeG)
3232
graph.addEdge(nodeE, neighbor: nodeH)
33-
33+
graph.addEdge(nodeE, neighbor: nodeF)
34+
graph.addEdge(nodeF, neighbor: nodeG)
3435

3536
let nodesExplored = depthFirstSearch(graph, source: nodeA)
3637
print(nodesExplored)
16.6 KB
Loading
Binary file not shown.
1.01 MB
Binary file not shown.
2.07 KB
Binary file not shown.
11.3 KB
Loading

Depth-First Search/README.markdown

+25-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,25 @@
22

33
Depth-first search (DFS) is an algorithm for traversing or searching [tree](../Tree/) or [graph](../Graph/) data structures. It starts at a source node and explores as far as possible along each branch before backtracking.
44

5-
[TODO: this is a work-in-progress]
5+
Depth-first search can be used on both directed and undirected graphs.
6+
7+
## Animated example
8+
9+
Here's how depth-first search works on a graph:
10+
11+
![Animated example](Images/AnimatedExample.gif)
12+
13+
Let's say we start the search from node `A`. In depth-first search we look at the starting node's first neighbor and visit that. In the example that is node `B`. Then we look at node `B`'s first neighbor and visit it. This is node `D`. Since `D` doesn't have any unvisited neighbors of its own, we backtrack to node `B` and go to its other neighbor `E`. And so on, until we've visited all the nodes in the graph.
14+
15+
Each time we visit the first neighbor and keep going until there's nowhere left to go, and then we backtrack to a point where there are again nodes to visit. When we've backtracked all the way to node `A`, the search is complete.
16+
17+
For the example, the nodes were visited in the order `A`, `B`, `D`, `E`, `H`, `F`, `G`, `C`.
18+
19+
The depth-first search process can also be visualized as a tree:
20+
21+
![Traversal tree](Images/TraversalTree.png)
22+
23+
The parent of a node is the one that "discovered" that node. The root of the tree is the node you started the depth-first search from. Whenever there's a branch, that's where we backtracked.
624

725
## The code
826

@@ -45,20 +63,22 @@ graph.addEdge(nodeB, neighbor: nodeE)
4563
graph.addEdge(nodeC, neighbor: nodeF)
4664
graph.addEdge(nodeC, neighbor: nodeG)
4765
graph.addEdge(nodeE, neighbor: nodeH)
66+
graph.addEdge(nodeE, neighbor: nodeF)
67+
graph.addEdge(nodeF, neighbor: nodeG)
4868

4969
let nodesExplored = depthFirstSearch(graph, source: nodeA)
5070
print(nodesExplored)
5171
```
5272

53-
This will output: `["a", "b", "d", "e", "h", "c", "f", "g"]`
73+
This will output: `["a", "b", "d", "e", "h", "f", "g", "c"]`
5474

55-
## Applications
75+
## What is DFS good for?
5676

5777
Depth-first search can be used to solve many problems, for example:
5878

5979
* Finding connected components of a sparse graph
60-
* Topological sorting of nodes in a graph
80+
* [Topological sorting](../Topological Sort/) of nodes in a graph
6181
* Finding bridges of a graph (see: [Bridges](https://en.wikipedia.org/wiki/Bridge_(graph_theory)#Bridge-finding_algorithm))
6282
* And lots of others!
6383

64-
*Written for Swift Algorithm Club by Paulo Tanaka*
84+
*Written for Swift Algorithm Club by Paulo Tanaka and Matthijs Hollemans*

Depth-First Search/Tests/DepthFirstSearchTests.swift

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ class DepthFirstSearchTests: XCTestCase {
44

55
func testExploringTree() {
66
let tree = Graph()
7+
78
let nodeA = tree.addNode("a")
89
let nodeB = tree.addNode("b")
910
let nodeC = tree.addNode("c")
@@ -12,6 +13,7 @@ class DepthFirstSearchTests: XCTestCase {
1213
let nodeF = tree.addNode("f")
1314
let nodeG = tree.addNode("g")
1415
let nodeH = tree.addNode("h")
16+
1517
tree.addEdge(nodeA, neighbor: nodeB)
1618
tree.addEdge(nodeA, neighbor: nodeC)
1719
tree.addEdge(nodeB, neighbor: nodeD)
@@ -70,7 +72,6 @@ class DepthFirstSearchTests: XCTestCase {
7072
let nodesExplored = depthFirstSearch(graph, source: nodeA)
7173

7274
XCTAssertEqual(nodesExplored, ["a", "b", "c", "d", "e", "f", "g", "h", "i"])
73-
7475
}
7576

7677
func testExploringGraphWithASingleNode() {
@@ -81,4 +82,4 @@ class DepthFirstSearchTests: XCTestCase {
8182

8283
XCTAssertEqual(nodesExplored, ["a"])
8384
}
84-
}
85+
}
File renamed without changes.

Depth-First Search/Tests/Tests.xcodeproj/project.pbxproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
7B2BBC801C779D720067B71D /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
1717
7B2BBC941C779E7B0067B71D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
1818
83F9C96B1C8443E800B3A87F /* DepthFirstSearchTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DepthFirstSearchTests.swift; sourceTree = SOURCE_ROOT; };
19-
83F9C96E1C84449D00B3A87F /* Graph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Graph.swift; path = ../Graph.swift; sourceTree = SOURCE_ROOT; };
19+
83F9C96E1C84449D00B3A87F /* Graph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Graph.swift; sourceTree = SOURCE_ROOT; };
2020
FFC6E11D1C8656D10046BA79 /* DepthFirstSearch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DepthFirstSearch.swift; path = ../DepthFirstSearch.swift; sourceTree = SOURCE_ROOT; };
2121
/* End PBXFileReference section */
2222

0 commit comments

Comments
 (0)