Skip to content

Commit 5196837

Browse files
committed
Incorporated reviews. changed isNullLeaf variable to a computed property
1 parent 8a24b2f commit 5196837

File tree

2 files changed

+43
-36
lines changed

2 files changed

+43
-36
lines changed

Red-Black Tree/RedBlackTree.playground/Contents.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,25 @@ let redBlackTree = RedBlackTree<Double>()
66

77
let randomMax = Double(0x10000000)
88
var values = [Double]()
9-
for _ in 0..<1000 {
9+
for i in 0..<1000 {
1010
let value = Double(arc4random()) / randomMax
1111
values.append(value)
1212
redBlackTree.insert(key: value)
13+
14+
if i % 100 == 0 {
15+
redBlackTree.verify()
16+
}
1317
}
1418
redBlackTree.verify()
1519

16-
for _ in 0..<1000 {
20+
for i in 0..<1000 {
1721
let rand = arc4random_uniform(UInt32(values.count))
1822
let index = Int(rand)
1923
let value = values.remove(at: index)
2024
redBlackTree.delete(key: value)
25+
26+
if i % 100 == 0 {
27+
redBlackTree.verify()
28+
}
2129
}
22-
redBlackTree.verify()
30+
redBlackTree.verify()

Red-Black Tree/RedBlackTree.playground/Sources/RedBlackTree.swift

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,16 @@ private enum RotationDirection {
3232

3333
// MARK: - RBNode
3434

35-
public class RBTreeNode<Key: Comparable>: Equatable {
36-
public typealias RBNode = RBTreeNode<Key>
35+
public class RBTreeNode<T: Comparable>: Equatable {
36+
public typealias RBNode = RBTreeNode<T>
3737

3838
fileprivate var color: RBTreeColor = .black
39-
fileprivate var key: Key?
40-
fileprivate var isNullLeaf = true
39+
fileprivate var key: T?
4140
var leftChild: RBNode?
4241
var rightChild: RBNode?
4342
fileprivate weak var parent: RBNode?
4443

45-
public init(key: Key?, leftChild: RBNode?, rightChild: RBNode?, parent: RBNode?) {
44+
public init(key: T?, leftChild: RBNode?, rightChild: RBNode?, parent: RBNode?) {
4645
self.key = key
4746
self.leftChild = leftChild
4847
self.rightChild = rightChild
@@ -52,16 +51,14 @@ public class RBTreeNode<Key: Comparable>: Equatable {
5251
self.rightChild?.parent = self
5352
}
5453

55-
public convenience init(key: Key?) {
54+
public convenience init(key: T?) {
5655
self.init(key: key, leftChild: RBNode(), rightChild: RBNode(), parent: RBNode())
57-
self.isNullLeaf = false
5856
}
5957

6058
// For initialising the nullLeaf
6159
public convenience init() {
6260
self.init(key: nil, leftChild: nil, rightChild: nil, parent: nil)
6361
self.color = .black
64-
self.isNullLeaf = true
6562
}
6663

6764
var isRoot: Bool {
@@ -72,7 +69,11 @@ public class RBTreeNode<Key: Comparable>: Equatable {
7269
return rightChild == nil && leftChild == nil
7370
}
7471

75-
var isLeftCild: Bool {
72+
var isNullLeaf: Bool {
73+
return key == nil && isLeaf && color == .black
74+
}
75+
76+
var isLeftChild: Bool {
7677
return parent?.leftChild === self
7778
}
7879

@@ -85,7 +86,7 @@ public class RBTreeNode<Key: Comparable>: Equatable {
8586
}
8687

8788
var sibling: RBNode? {
88-
if isLeftCild {
89+
if isLeftChild {
8990
return parent?.rightChild
9091
} else {
9192
return parent?.leftChild
@@ -99,8 +100,8 @@ public class RBTreeNode<Key: Comparable>: Equatable {
99100

100101
// MARK: - RedBlackTree
101102

102-
public class RedBlackTree<Key: Comparable> {
103-
public typealias RBNode = RBTreeNode<Key>
103+
public class RedBlackTree<T: Comparable> {
104+
public typealias RBNode = RBTreeNode<T>
104105

105106
fileprivate(set) var root: RBNode
106107
fileprivate(set) var size = 0
@@ -180,14 +181,14 @@ extension RedBlackTree {
180181
/*
181182
* Returns the node with the given key |input| if existing
182183
*/
183-
public func search(input: Key) -> RBNode? {
184+
public func search(input: T) -> RBNode? {
184185
return search(key: input, node: root)
185186
}
186187

187188
/*
188189
* Returns the node with given |key| in subtree of |node|
189190
*/
190-
fileprivate func search(key: Key, node: RBNode?) -> RBNode? {
191+
fileprivate func search(key: T, node: RBNode?) -> RBNode? {
191192
// If node nil -> key not found
192193
guard let node = node else {
193194
return nil
@@ -215,23 +216,21 @@ extension RedBlackTree {
215216
/*
216217
* Returns the minimum key value of the whole tree
217218
*/
218-
public func minValue() -> Key? {
219-
if let minNode = root.minimum() {
220-
return minNode.key
221-
} else {
219+
public func minValue() -> T? {
220+
guard let minNode = root.minimum() else {
222221
return nil
223222
}
223+
return minNode.key
224224
}
225225

226226
/*
227227
* Returns the maximum key value of the whole tree
228228
*/
229-
public func maxValue() -> Key? {
230-
if let maxNode = root.maximum() {
231-
return maxNode.key
232-
} else {
233-
return nil
229+
public func maxValue() -> T? {
230+
guard let maxNode = root.maximum() else {
231+
return nil
234232
}
233+
return maxNode.key
235234
}
236235
}
237236

@@ -244,7 +243,7 @@ extension RedBlackTree {
244243
* 2. Fix red-black properties
245244
* Runntime: O(log n)
246245
*/
247-
public func insert(key: Key) {
246+
public func insert(key: T) {
248247
if root.isNullLeaf {
249248
root = RBNode(key: key)
250249
} else {
@@ -332,18 +331,18 @@ extension RedBlackTree {
332331
else {
333332
var zNew = z
334333
// Case 2.a: z right child -> rotate
335-
if parentZ.isLeftCild && z.isRightChild {
334+
if parentZ.isLeftChild && z.isRightChild {
336335
zNew = parentZ
337336
leftRotate(node: zNew)
338-
} else if parentZ.isRightChild && z.isLeftCild {
337+
} else if parentZ.isRightChild && z.isLeftChild {
339338
zNew = parentZ
340339
rightRotate(node: zNew)
341340
}
342341
// Case 2.b: z left child -> recolor + rotate
343342
zNew.parent?.color = .black
344343
if let grandparentZnew = zNew.grandparent {
345344
grandparentZnew.color = .red
346-
if z.isLeftCild {
345+
if z.isLeftChild {
347346
rightRotate(node: grandparentZnew)
348347
} else {
349348
leftRotate(node: grandparentZnew)
@@ -365,7 +364,7 @@ extension RedBlackTree {
365364
* 2. Fix red-black properties
366365
* Runntime: O(log n)
367366
*/
368-
public func delete(key: Key) {
367+
public func delete(key: T) {
369368
if size == 1 {
370369
root = nullLeaf
371370
size -= 1
@@ -408,7 +407,7 @@ extension RedBlackTree {
408407
if parentY.isNullLeaf {
409408
root = nodeX
410409
} else {
411-
if nodeY.isLeftCild {
410+
if nodeY.isLeftChild {
412411
parentY.leftChild = nodeX
413412
} else {
414413
parentY.rightChild = nodeX
@@ -450,7 +449,7 @@ extension RedBlackTree {
450449
if let parentX = x.parent {
451450
parentX.color = .red
452451
// Rotation
453-
if x.isLeftCild {
452+
if x.isLeftChild {
454453
leftRotate(node: parentX)
455454
} else {
456455
rightRotate(node: parentX)
@@ -472,7 +471,7 @@ extension RedBlackTree {
472471
// We have a valid red-black-tree
473472
} else {
474473
// Case 3: a. Sibling black with one black child to the right
475-
if x.isLeftCild && sibling.rightChild?.color == .black {
474+
if x.isLeftChild && sibling.rightChild?.color == .black {
476475
// Recolor
477476
sibling.leftChild?.color = .black
478477
sibling.color = .red
@@ -501,7 +500,7 @@ extension RedBlackTree {
501500
sibling.color = parentX.color
502501
parentX.color = .black
503502
// a. x left and sibling with red right child
504-
if x.isLeftCild {
503+
if x.isLeftChild {
505504
sibling.rightChild?.color = .black
506505
// Rotate
507506
leftRotate(node: parentX)
@@ -581,7 +580,7 @@ extension RedBlackTree {
581580
if let node = nodeY {
582581
root = node
583582
}
584-
} else if x.isLeftCild {
583+
} else if x.isLeftChild {
585584
x.parent?.leftChild = nodeY
586585
} else if x.isRightChild {
587586
x.parent?.rightChild = nodeY

0 commit comments

Comments
 (0)