Skip to content

Commit ea4532a

Browse files
committed
Tweaks to binary search tree
1 parent 5f0ea9b commit ea4532a

File tree

2 files changed

+69
-55
lines changed

2 files changed

+69
-55
lines changed
Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,47 @@
11
import Foundation
22

33
public enum BinarySearchTree<T: Comparable> {
4-
indirect case Node(BinarySearchTree, T, BinarySearchTree)
5-
case Leaf(T)
6-
case Empty
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+
}
716

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-
}
17+
case .Empty:
18+
return .Leaf(new)
2619

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-
}
20+
case .Node(let left, let value, let right):
21+
if new < value {
22+
return .Node(left.insert(new), value, right)
23+
} else {
24+
return .Node(left, value, right.insert(new))
25+
}
26+
}
27+
}
28+
29+
public var height: Int {
30+
switch self {
31+
case .Empty: return 0
32+
case .Leaf(_): return 1
33+
case .Node(let left, _, let right): return 1 + max(left.height, right.height)
3334
}
35+
}
3436
}
3537

3638
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-
}
39+
var debugDescription: String {
40+
switch self {
41+
case .Empty: return "<X>"
42+
case .Leaf(let v): return "\(v)"
43+
case .Node(let left, let value, let right):
44+
return "(\(left.debugDescription) <- \(value) -> \(right.debugDescription))"
4345
}
46+
}
4447
}

Binary Search Tree/README.markdown

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,63 @@
1-
# Heap
1+
# Binary Search Tree (BST)
22

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.
3+
A binary search tree is a special kind of [binary tree](../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.
84

95
## "Always sorted" property
106

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

139
Let's look at an example:
1410

1511
```
16-
(7)
17-
/ \
18-
(2) (10)
19-
/ \
20-
(1) (5)
12+
(7)
13+
/ \
14+
(2) (10)
15+
/ \
16+
(1) (5)
2117
```
2218

23-
Say we want to insert the value 9:
19+
Notice how each left child is smaller than its parent node, and each right child is greater than its parent node. For example, `2` is smaller than `7` so it goes on the left; `5` is greater than `2` so it goes on the right.
20+
21+
Say we want to insert the new value `9`:
2422

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:
23+
- We start at the root of the tree (the node with the value `7`) and compare it to the new value `9`.
24+
- We see that `9 > 7`, so we go down the *right* branch of that node and perform the same procedure: check against the key, but this time `9 < 10`, so we go down the *left* branch.
25+
- 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.
26+
27+
The tree now looks like this:
2828

2929
```
30-
(7)
31-
/ \
32-
(2) (10)
33-
/ \ /
34-
(1) (5) (9)
30+
(7)
31+
/ \
32+
(2) (10)
33+
/ \ /
34+
(1) (5) (9)
3535
```
3636

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

39+
## Searching the tree
40+
41+
[TBD: explain how you'd search the tree and why it is fast; compare with the binary search article]
42+
3943
## Deletion
4044

4145
TBD
4246

47+
## The code
48+
49+
[TBD: explain how you've implemented the tree in Swift]
50+
4351
## Disadvantages
4452

4553
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.
54+
4655
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.
4756

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.
57+
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 child nodes branching in the same direction.
4958

5059
## See also
5160

5261
[Binary Search Tree on Wikipedia](https://en.wikipedia.org/wiki/Binary_search_tree)
62+
63+
*Written for the Swift Algorithm Club by [Nicolas Ameghino](http://www.github.com/nameghino).*

0 commit comments

Comments
 (0)