Skip to content

Commit c2473df

Browse files
author
Chris Pilcher
authored
Merge pull request kodecocodes#192 from chris-pilcher/union-find-swift3
Updating Union-Find to Swift 3
2 parents dca75c0 + 93e1eea commit c2473df

File tree

3 files changed

+25
-25
lines changed

3 files changed

+25
-25
lines changed

Union-Find/README.markdown

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ What do we mean by this? For example, the Union-Find data structure could be kee
99
[ g, d, c ]
1010
[ i, j ]
1111

12-
These sets are disjoint because they have no members in common.
12+
These sets are disjoint because they have no members in common.
1313

1414
Union-Find supports three basic operations:
1515

@@ -41,9 +41,9 @@ Example: If `parent` looks like this,
4141

4242
parent [ 1, 1, 1, 0, 2, 0, 6, 6, 6 ]
4343
i 0 1 2 3 4 5 6 7 8
44-
44+
4545
then the tree structure looks like:
46-
46+
4747
1 6
4848
/ \ / \
4949
0 2 7 8
@@ -63,7 +63,7 @@ Note that the `parent[]` of a root node points to itself. So `parent[1] = 1` and
6363
Let's look at the implementation of these basic operations, starting with adding a new set.
6464

6565
```swift
66-
public mutating func addSetWith(element: T) {
66+
public mutating func addSetWith(_ element: T) {
6767
index[element] = parent.count // 1
6868
parent.append(parent.count) // 2
6969
size.append(1) // 3
@@ -83,7 +83,7 @@ When you add a new element, this actually adds a new subset containing just that
8383
Often we want to determine whether we already have a set that contains a given element. That's what the **Find** operation does. In our `UnionFind` data structure it is called `setOf()`:
8484

8585
```swift
86-
public mutating func setOf(element: T) -> Int? {
86+
public mutating func setOf(_ element: T) -> Int? {
8787
if let indexOfElement = index[element] {
8888
return setByIndex(indexOfElement)
8989
} else {
@@ -95,7 +95,7 @@ public mutating func setOf(element: T) -> Int? {
9595
This looks up the element's index in the `index` dictionary and then uses a helper method to find the set that this element belongs to:
9696

9797
```swift
98-
private mutating func setByIndex(index: Int) -> Int {
98+
private mutating func setByIndex(_ index: Int) -> Int {
9999
if parent[index] == index { // 1
100100
return index
101101
} else {
@@ -109,7 +109,7 @@ Because we're dealing with a tree structure, this is a recursive method.
109109

110110
Recall that each set is represented by a tree and that the index of the root node serves as the number that identifies the set. We're going to find the root node of the tree that the element we're searching for belongs to, and return its index.
111111

112-
1. First, we check if the given index represents a root node (i.e. a node whose `parent` points back to the node itself). If so, we're done.
112+
1. First, we check if the given index represents a root node (i.e. a node whose `parent` points back to the node itself). If so, we're done.
113113

114114
2. Otherwise we recursively call this method on the parent of the current node. And then we do a **very important thing**: we overwrite the parent of the current node with the index of root node, in effect reconnecting the node directly to the root of the tree. The next time we call this method, it will execute faster because the path to the root of the tree is now much shorter. Without that optimization, this method's complexity is **O(n)** but now in combination with the size optimization (covered in the Union section) it is almost **O(1)**.
115115

@@ -130,8 +130,8 @@ Now if we need to call `setOf(4)` again, we no longer have to go through node `2
130130
There is also a helper method to check that two elements are in the same set:
131131

132132
```swift
133-
public mutating func inSameSet(firstElement: T, and secondElement: T) -> Bool {
134-
if let firstSet = setOf(firstElement), secondSet = setOf(secondElement) {
133+
public mutating func inSameSet(_ firstElement: T, and secondElement: T) -> Bool {
134+
if let firstSet = setOf(firstElement), let secondSet = setOf(secondElement) {
135135
return firstSet == secondSet
136136
} else {
137137
return false
@@ -146,8 +146,8 @@ Since this calls `setOf()` it also optimizes the tree.
146146
The final operation is **Union**, which combines two sets into one larger set.
147147

148148
```swift
149-
public mutating func unionSetsContaining(firstElement: T, and secondElement: T) {
150-
if let firstSet = setOf(firstElement), secondSet = setOf(secondElement) { // 1
149+
public mutating func unionSetsContaining(_ firstElement: T, and secondElement: T) {
150+
if let firstSet = setOf(firstElement), let secondSet = setOf(secondElement) { // 1
151151
if firstSet != secondSet { // 2
152152
if size[firstSet] < size[secondSet] { // 3
153153
parent[firstSet] = secondSet // 4

Union-Find/UnionFind.playground/Contents.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ public struct UnionFind<T: Hashable> {
55
private var parent = [Int]()
66
private var size = [Int]()
77

8-
public mutating func addSetWith(element: T) {
8+
public mutating func addSetWith(_ element: T) {
99
index[element] = parent.count
1010
parent.append(parent.count)
1111
size.append(1)
1212
}
1313

14-
private mutating func setByIndex(index: Int) -> Int {
14+
private mutating func setByIndex(_ index: Int) -> Int {
1515
if parent[index] == index {
1616
return index
1717
} else {
@@ -20,16 +20,16 @@ public struct UnionFind<T: Hashable> {
2020
}
2121
}
2222

23-
public mutating func setOf(element: T) -> Int? {
23+
public mutating func setOf(_ element: T) -> Int? {
2424
if let indexOfElement = index[element] {
2525
return setByIndex(indexOfElement)
2626
} else {
2727
return nil
2828
}
2929
}
3030

31-
public mutating func unionSetsContaining(firstElement: T, and secondElement: T) {
32-
if let firstSet = setOf(firstElement), secondSet = setOf(secondElement) {
31+
public mutating func unionSetsContaining(_ firstElement: T, and secondElement: T) {
32+
if let firstSet = setOf(firstElement), let secondSet = setOf(secondElement) {
3333
if firstSet != secondSet {
3434
if size[firstSet] < size[secondSet] {
3535
parent[firstSet] = secondSet
@@ -42,8 +42,8 @@ public struct UnionFind<T: Hashable> {
4242
}
4343
}
4444

45-
public mutating func inSameSet(firstElement: T, and secondElement: T) -> Bool {
46-
if let firstSet = setOf(firstElement), secondSet = setOf(secondElement) {
45+
public mutating func inSameSet(_ firstElement: T, and secondElement: T) -> Bool {
46+
if let firstSet = setOf(firstElement), let secondSet = setOf(secondElement) {
4747
return firstSet == secondSet
4848
} else {
4949
return false

Union-Find/UnionFind.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ public struct UnionFind<T: Hashable> {
1212
private var parent = [Int]()
1313
private var size = [Int]()
1414

15-
public mutating func addSetWith(element: T) {
15+
public mutating func addSetWith(_ element: T) {
1616
index[element] = parent.count
1717
parent.append(parent.count)
1818
size.append(1)
1919
}
2020

21-
private mutating func setByIndex(index: Int) -> Int {
21+
private mutating func setByIndex(_ index: Int) -> Int {
2222
if parent[index] == index {
2323
return index
2424
} else {
@@ -27,16 +27,16 @@ public struct UnionFind<T: Hashable> {
2727
}
2828
}
2929

30-
public mutating func setOf(element: T) -> Int? {
30+
public mutating func setOf(_ element: T) -> Int? {
3131
if let indexOfElement = index[element] {
3232
return setByIndex(indexOfElement)
3333
} else {
3434
return nil
3535
}
3636
}
3737

38-
public mutating func unionSetsContaining(firstElement: T, and secondElement: T) {
39-
if let firstSet = setOf(firstElement), secondSet = setOf(secondElement) {
38+
public mutating func unionSetsContaining(_ firstElement: T, and secondElement: T) {
39+
if let firstSet = setOf(firstElement), let secondSet = setOf(secondElement) {
4040
if firstSet != secondSet {
4141
if size[firstSet] < size[secondSet] {
4242
parent[firstSet] = secondSet
@@ -49,8 +49,8 @@ public struct UnionFind<T: Hashable> {
4949
}
5050
}
5151

52-
public mutating func inSameSet(firstElement: T, and secondElement: T) -> Bool {
53-
if let firstSet = setOf(firstElement), secondSet = setOf(secondElement) {
52+
public mutating func inSameSet(_ firstElement: T, and secondElement: T) -> Bool {
53+
if let firstSet = setOf(firstElement), let secondSet = setOf(secondElement) {
5454
return firstSet == secondSet
5555
} else {
5656
return false

0 commit comments

Comments
 (0)