Skip to content

Commit

Permalink
Updating to Swift 3
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Pilcher committed Aug 30, 2016
1 parent 21b05b1 commit 93e1eea
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 25 deletions.
22 changes: 11 additions & 11 deletions Union-Find/README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ What do we mean by this? For example, the Union-Find data structure could be kee
[ g, d, c ]
[ i, j ]

These sets are disjoint because they have no members in common.
These sets are disjoint because they have no members in common.

Union-Find supports three basic operations:

Expand Down Expand Up @@ -41,9 +41,9 @@ Example: If `parent` looks like this,

parent [ 1, 1, 1, 0, 2, 0, 6, 6, 6 ]
i 0 1 2 3 4 5 6 7 8

then the tree structure looks like:

1 6
/ \ / \
0 2 7 8
Expand All @@ -63,7 +63,7 @@ Note that the `parent[]` of a root node points to itself. So `parent[1] = 1` and
Let's look at the implementation of these basic operations, starting with adding a new set.

```swift
public mutating func addSetWith(element: T) {
public mutating func addSetWith(_ element: T) {
index[element] = parent.count // 1
parent.append(parent.count) // 2
size.append(1) // 3
Expand All @@ -83,7 +83,7 @@ When you add a new element, this actually adds a new subset containing just that
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()`:

```swift
public mutating func setOf(element: T) -> Int? {
public mutating func setOf(_ element: T) -> Int? {
if let indexOfElement = index[element] {
return setByIndex(indexOfElement)
} else {
Expand All @@ -95,7 +95,7 @@ public mutating func setOf(element: T) -> Int? {
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:

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

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.

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.
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.

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)**.

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

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

```swift
public mutating func unionSetsContaining(firstElement: T, and secondElement: T) {
if let firstSet = setOf(firstElement), secondSet = setOf(secondElement) { // 1
public mutating func unionSetsContaining(_ firstElement: T, and secondElement: T) {
if let firstSet = setOf(firstElement), let secondSet = setOf(secondElement) { // 1
if firstSet != secondSet { // 2
if size[firstSet] < size[secondSet] { // 3
parent[firstSet] = secondSet // 4
Expand Down
14 changes: 7 additions & 7 deletions Union-Find/UnionFind.playground/Contents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ public struct UnionFind<T: Hashable> {
private var parent = [Int]()
private var size = [Int]()

public mutating func addSetWith(element: T) {
public mutating func addSetWith(_ element: T) {
index[element] = parent.count
parent.append(parent.count)
size.append(1)
}

private mutating func setByIndex(index: Int) -> Int {
private mutating func setByIndex(_ index: Int) -> Int {
if parent[index] == index {
return index
} else {
Expand All @@ -20,16 +20,16 @@ public struct UnionFind<T: Hashable> {
}
}

public mutating func setOf(element: T) -> Int? {
public mutating func setOf(_ element: T) -> Int? {
if let indexOfElement = index[element] {
return setByIndex(indexOfElement)
} else {
return nil
}
}

public mutating func unionSetsContaining(firstElement: T, and secondElement: T) {
if let firstSet = setOf(firstElement), secondSet = setOf(secondElement) {
public mutating func unionSetsContaining(_ firstElement: T, and secondElement: T) {
if let firstSet = setOf(firstElement), let secondSet = setOf(secondElement) {
if firstSet != secondSet {
if size[firstSet] < size[secondSet] {
parent[firstSet] = secondSet
Expand All @@ -42,8 +42,8 @@ public struct UnionFind<T: Hashable> {
}
}

public mutating func inSameSet(firstElement: T, and secondElement: T) -> Bool {
if let firstSet = setOf(firstElement), secondSet = setOf(secondElement) {
public mutating func inSameSet(_ firstElement: T, and secondElement: T) -> Bool {
if let firstSet = setOf(firstElement), let secondSet = setOf(secondElement) {
return firstSet == secondSet
} else {
return false
Expand Down
14 changes: 7 additions & 7 deletions Union-Find/UnionFind.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ public struct UnionFind<T: Hashable> {
private var parent = [Int]()
private var size = [Int]()

public mutating func addSetWith(element: T) {
public mutating func addSetWith(_ element: T) {
index[element] = parent.count
parent.append(parent.count)
size.append(1)
}

private mutating func setByIndex(index: Int) -> Int {
private mutating func setByIndex(_ index: Int) -> Int {
if parent[index] == index {
return index
} else {
Expand All @@ -27,16 +27,16 @@ public struct UnionFind<T: Hashable> {
}
}

public mutating func setOf(element: T) -> Int? {
public mutating func setOf(_ element: T) -> Int? {
if let indexOfElement = index[element] {
return setByIndex(indexOfElement)
} else {
return nil
}
}

public mutating func unionSetsContaining(firstElement: T, and secondElement: T) {
if let firstSet = setOf(firstElement), secondSet = setOf(secondElement) {
public mutating func unionSetsContaining(_ firstElement: T, and secondElement: T) {
if let firstSet = setOf(firstElement), let secondSet = setOf(secondElement) {
if firstSet != secondSet {
if size[firstSet] < size[secondSet] {
parent[firstSet] = secondSet
Expand All @@ -49,8 +49,8 @@ public struct UnionFind<T: Hashable> {
}
}

public mutating func inSameSet(firstElement: T, and secondElement: T) -> Bool {
if let firstSet = setOf(firstElement), secondSet = setOf(secondElement) {
public mutating func inSameSet(_ firstElement: T, and secondElement: T) -> Bool {
if let firstSet = setOf(firstElement), let secondSet = setOf(secondElement) {
return firstSet == secondSet
} else {
return false
Expand Down

0 comments on commit 93e1eea

Please sign in to comment.