Skip to content

Commit e5c22d6

Browse files
author
Chris Pilcher
committed
Merge branch 'master' of https://github.com/hollance/swift-algorithm-club into Select-Minimum-Maximum
2 parents dc0ddb8 + 29fb51e commit e5c22d6

File tree

8 files changed

+184
-4
lines changed

8 files changed

+184
-4
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import Foundation
2+
3+
public enum BinarySearchTree<T: Comparable> {
4+
indirect case Node(BinarySearchTree, T, BinarySearchTree)
5+
case Leaf(T)
6+
case Empty
7+
8+
public func insert(new: T) -> BinarySearchTree {
9+
switch self {
10+
case .Leaf(let value):
11+
if new < value {
12+
return .Node(.Leaf(new), value, .Empty)
13+
} else {
14+
return .Node(.Empty, value, .Leaf(new))
15+
}
16+
case .Empty:
17+
return .Leaf(new)
18+
case .Node(let left, let value, let right):
19+
if new < value {
20+
return .Node(left.insert(new), value, right)
21+
} else {
22+
return .Node(left, value, right.insert(new))
23+
}
24+
}
25+
}
26+
27+
public var height: Int {
28+
switch self {
29+
case .Empty: return 0
30+
case .Leaf(_): return 1
31+
case .Node(let left, _, let right): return 1 + max(left.height, right.height)
32+
}
33+
}
34+
}
35+
36+
extension BinarySearchTree: CustomDebugStringConvertible {
37+
var debugDescription: String {
38+
switch self {
39+
case .Empty: return "<X>"
40+
case .Leaf(let v): return "\(v)"
41+
case .Node(let left, let value, let right): return "(\(left.debugDescription) <- \(value) -> \(right.debugDescription))"
42+
}
43+
}
44+
}

Binary Search Tree/README.markdown

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Heap
2+
3+
Written for the Swift Algorithm Club by [Nicolas Ameghino](http://www.github.com/nameghino).
4+
5+
## Intro
6+
7+
A binary search tree is a special kind of binary tree (a tree in which a node only has two children) that performs insertions in a special way such that the tree is always sorted.
8+
9+
## "Always sorted" property
10+
11+
When performing an insertion, the tree will check the value of the *key* for a node and compare it to the *key* for the soon-to-be-inserted value. It will go down the tree until there's an empty leaf following the rule that if the new value is smaller than the existant one, it will be inserted to the left of the existant node. Otherwise, it will be to the right of it.
12+
13+
Let's look at an example:
14+
15+
```
16+
(7)
17+
/ \
18+
(2) (10)
19+
/ \
20+
(1) (5)
21+
```
22+
23+
Say we want to insert the value 9:
24+
25+
We'd start at the root of the tree (the node with the value 7, in this case), and compare it to the new value (9 for now).
26+
We see that `9 > 7`, so we go down the *right* branch of that node. Here, we recurse on the *right* node, and peform the same procedure: check against the key, but this time `9 < 10`, so we go down the *left* branch.
27+
We've now arrived to a point in which there are no more values to compare with, so the value 9 is inserted at that ___location, going first right and then left from the root, to have a tree that now looks like this:
28+
29+
```
30+
(7)
31+
/ \
32+
(2) (10)
33+
/ \ /
34+
(1) (5) (9)
35+
```
36+
37+
By following this simple rule, we keep the tree sorted in a way that, whenever we query it, we can quickly check if a value is in the tree or get such value.
38+
39+
## Deletion
40+
41+
TBD
42+
43+
## Disadvantages
44+
45+
If the tree is not *balanced*, that is, one branch is significantly longer than the other, then queries would suffer performance issues, having to check more values on one branch than it would if the tree were optimally balanced.
46+
Balanced trees guarantee that the longest branch of the tree will be at most 1 node longer than the rest, otherwise the tree will balance itself on insertion.
47+
48+
Another issue arises from the insertion of increasing or decreasing values, in which the tree would be massively unbalanced with just one long branch, and all children nodes branching in the same direction.
49+
50+
## See also
51+
52+
[Binary Search Tree on Wikipedia](https://en.wikipedia.org/wiki/Binary_search_tree)

Kth Largest Element/README.markdown

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# k-th Largest Element Problem
2+
3+
You're given an integer array `a`. Write an algorithm that finds the kth largest element in the array.
4+
5+
The following solution is semi-naive. Its time complexity is O(n log n) since it first sorts the array, and uses an additional O(n) space. Better solutions using heaps exist that run in O(n) time.
6+
7+
```swift
8+
func kthLargest(a: [Int], k: Int) -> Int? {
9+
let len = a.count
10+
11+
if (k <= 0 || k > len || len < 1) { return nil }
12+
13+
let sorted = a.sort()
14+
15+
return sorted[len - k]
16+
}
17+
```
18+
19+
The `kthLargest()` function takes two parameters: the array `a` with consisting of integers, and `k`, in order to find the kth largest element. It returns the kth largest element.
20+
21+
Let's take a look at an example and run through the algorithm to see how it works. Given `k = 4` and the array:
22+
23+
```swift
24+
[ 7, 92, 23, 9, -1, 0, 11, 6 ]
25+
```
26+
27+
Initially there's no direct way to find the kth largest element, but after sorting the array it's rather straightforward. Here's the sorted array:
28+
29+
```swift
30+
[ -1, 0, 6, 7, 9, 11, 23, 92 ]
31+
```
32+
33+
Now, all we must do is take the kth largest value, which is located at: `a[a.count - k] = a[8 - 4] = a[4] = 9`
34+
35+
*Written by Daniel Speiser*
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Returns the k-th largest value inside of an array a.
3+
* This is an O(n log n) solution since we sort the array.
4+
*/
5+
func kthLargest(a: [Int], k: Int) -> Int? {
6+
let len = a.count
7+
8+
if (k <= 0 || k > len || len < 1) { return nil }
9+
10+
let sorted = a.sort()
11+
12+
return sorted[len - k]
13+
}
14+
15+
let a = [5, 1, 3, 2, 7, 6, 4]
16+
17+
kthLargest(a, k: 0)
18+
kthLargest(a, k: 1)
19+
kthLargest(a, k: 2)
20+
kthLargest(a, k: 3)
21+
kthLargest(a, k: 4)
22+
kthLargest(a, k: 5)
23+
kthLargest(a, k: 6)
24+
kthLargest(a, k: 7)
25+
kthLargest(a, k: 8)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<playground version='5.0' target-platform='osx'>
3+
<timeline fileName='timeline.xctimeline'/>
4+
</playground>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Timeline
3+
version = "3.0">
4+
<TimelineItems>
5+
</TimelineItems>
6+
</Timeline>

Kth Largest Element/kthLargest.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
* Returns the k-th largest value inside of an array a.
3+
* This is an O(n log n) solution since we sort the array.
4+
*/
5+
func kthLargest(a: [Int], k: Int) -> Int? {
6+
let len = a.count
7+
8+
if (k <= 0 || k > len || len < 1) { return nil }
9+
10+
let sorted = a.sort()
11+
12+
return sorted[len - k]
13+
}

README.markdown

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ If you're new to algorithms and data structures, here are a few good ones to sta
4141
- Binary Tree
4242
- Merge Sort
4343
- [Boyer-Moore](Boyer-Moore/) string search
44+
- [Binary Search Tree](Binary Search Tree/)
4445

4546
## The algorithms
4647

@@ -50,7 +51,7 @@ If you're new to algorithms and data structures, here are a few good ones to sta
5051
- [Binary Search](Binary Search/). Quickly find elements in a sorted array.
5152
- [Count Occurrences](Count Occurrences/). Count how often a value appears in an array.
5253
- [Select Minimum / Maximum](Select Minimum Maximum). Find the minimum/maximum value in an array.
53-
- Select k-th Largest Element
54+
- [k-th Largest Element](Kth Largest Element/). Find the kth largest element in an array.
5455
- Selection Sampling
5556
- Union-Find
5657

@@ -106,7 +107,7 @@ Bad sorting algorithms (don't use these!):
106107

107108
## Data structures
108109

109-
The choice of data structure for a particular task depends on a few things.
110+
The choice of data structure for a particular task depends on a few things.
110111

111112
First, there is the shape of your data and the kinds of operations that you'll need to perform on it. If you want to look up objects by a key you need some kind of dictionary; if your data is hierarchical in nature you want a tree structure of some sort; if your data is sequential you want a stack or queue.
112113

@@ -136,7 +137,7 @@ Often just using the built-in `Array`, `Dictionary`, and `Set` types is sufficie
136137

137138
- [Tree](Tree/). A general-purpose tree structure.
138139
- Binary Tree
139-
- Binary Search Tree (BST)
140+
- [Binary Search Tree (BST)](Binary Search Tree/). A binary tree with the special requirement that elements are inserted in a specific way, allowing for faster queries, like when using a [binary search](Binary Search/) algorithm.
140141
- AVL Tree
141142
- Red-Black Tree
142143
- Splay Tree
@@ -156,7 +157,7 @@ Often just using the built-in `Array`, `Dictionary`, and `Set` types is sufficie
156157

157158
### Hashing
158159

159-
- [Hash Table](Hash Table/). Allows you to store and retrieve objects by a key. This is how the dictionary type is usually implemented.
160+
- [Hash Table](Hash Table/). Allows you to store and retrieve objects by a key. This is how the dictionary type is usually implemented.
160161
- Hash Functions
161162

162163
### Graphs

0 commit comments

Comments
 (0)