Skip to content

Commit d663d5d

Browse files
committed
changed sibling property to be non optional and fixed insertion bug
1 parent a5397bb commit d663d5d

File tree

2 files changed

+72
-51
lines changed

2 files changed

+72
-51
lines changed
Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
//: Playground - noun: a place where people can play
2+
import Foundation
23

3-
let array = [6,78,89,4]
4-
var tree = RBTree<Int>(withArray: array)
5-
tree.insert(5)
6-
tree.insert(8)
7-
tree.insert(2)
8-
tree.delete(6)
9-
tree.delete(8)
4+
let tree = RBTree<Double>()
5+
let randomMax = Double(0x100000000)
6+
var values = [Double]()
7+
for _ in 0..<1000 {
8+
let value = Double(arc4random()) / randomMax
9+
values.append(value)
10+
tree.insert(value)
11+
}
12+
tree.verify()
13+
14+
for _ in 0..<1000 {
15+
let rand = arc4random_uniform(UInt32(values.count))
16+
let index = Int(rand)
17+
let value = values.remove(at: index)
18+
tree.delete(value)
19+
}
20+
tree.verify()

Red-Black Tree 2/Red-Black Tree 2.playground/Sources/RBTree.swift

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,11 @@ public class RBTNode<T: Comparable>: CustomStringConvertible {
5555
return parent.parent
5656
}
5757

58-
public var sibling: RBTNode<T>! {
58+
public var sibling: RBTNode<T> {
5959
if isLeftChild {
6060
return self.parent.right
61-
} else if isRightChild {
62-
return self.parent.left
6361
} else {
64-
return nil
62+
return self.parent.left
6563
}
6664
}
6765

@@ -245,6 +243,8 @@ public class RBTree<T: Comparable>: CustomStringConvertible {
245243
} else if n.parent.isRightChild && n.isLeftChild { // right left case
246244
rightRotate(n: n.parent)
247245
insertCase5(n: n.right)
246+
} else {
247+
insertCase5(n: n)
248248
}
249249
}
250250

@@ -320,81 +320,91 @@ public class RBTree<T: Comparable>: CustomStringConvertible {
320320
child.color = .doubleBlack
321321

322322
while child.isDoubleBlack || (child.parent !== nullLeaf && child.parent != nil) {
323-
if sibling!.isBlack {
323+
if sibling.isBlack {
324324

325325
var leftRedChild: RBTNode<T>! = nil
326-
if sibling!.left.isRed {
327-
leftRedChild = sibling!.left
326+
if sibling.left.isRed {
327+
leftRedChild = sibling.left
328328
}
329329
var rightRedChild: RBTNode<T>! = nil
330-
if sibling!.right.isRed {
331-
rightRedChild = sibling!.right
330+
if sibling.right.isRed {
331+
rightRedChild = sibling.right
332332
}
333333

334334
if leftRedChild != nil || rightRedChild != nil { // at least one of sibling's children are red
335335
child.color = .black
336-
if sibling!.isLeftChild {
336+
if sibling.isLeftChild {
337337
if leftRedChild != nil { // left left case
338-
sibling!.left.color = .black
339-
let tempColor = sibling!.parent.color
340-
sibling!.parent.color = sibling!.color
341-
sibling!.color = tempColor
342-
rightRotate(n: sibling!.parent)
338+
sibling.left.color = .black
339+
let tempColor = sibling.parent.color
340+
sibling.parent.color = sibling.color
341+
sibling.color = tempColor
342+
rightRotate(n: sibling.parent)
343343
} else { // left right case
344-
if sibling!.parent.isRed {
345-
sibling!.parent.color = .black
344+
if sibling.parent.isRed {
345+
sibling.parent.color = .black
346346
} else {
347-
sibling!.right.color = .black
347+
sibling.right.color = .black
348348
}
349-
leftRotate(n: sibling!)
350-
rightRotate(n: sibling!.grandparent)
349+
leftRotate(n: sibling)
350+
rightRotate(n: sibling.grandparent)
351351
}
352352
} else {
353353
if rightRedChild != nil { // right right case
354-
sibling!.right.color = .black
355-
let tempColor = sibling!.parent.color
356-
sibling!.parent.color = sibling!.color
357-
sibling!.color = tempColor
358-
leftRotate(n: sibling!.parent)
354+
sibling.right.color = .black
355+
let tempColor = sibling.parent.color
356+
sibling.parent.color = sibling.color
357+
sibling.color = tempColor
358+
leftRotate(n: sibling.parent)
359359
} else { // right left case
360-
if sibling!.parent.isRed {
361-
sibling!.parent.color = .black
360+
if sibling.parent.isRed {
361+
sibling.parent.color = .black
362362
} else {
363-
sibling!.left.color = .black
363+
sibling.left.color = .black
364364
}
365-
rightRotate(n: sibling!)
366-
leftRotate(n: sibling!.grandparent)
365+
rightRotate(n: sibling)
366+
leftRotate(n: sibling.grandparent)
367367
}
368368
}
369369
break
370370
} else { // both sibling's children are black
371371
child.color = .black
372-
sibling!.color = .red
373-
if sibling!.parent.isRed {
374-
sibling!.parent.color = .black
372+
sibling.color = .red
373+
if sibling.parent.isRed {
374+
sibling.parent.color = .black
375375
break
376376
}
377-
sibling!.parent.color = .doubleBlack
378-
child = sibling!.parent
377+
/*
378+
sibling.parent.color = .doubleBlack
379+
child = sibling.parent
379380
sibling = child.sibling
381+
*/
382+
if sibling.parent.parent === nullLeaf { // parent of child is root
383+
break
384+
} else {
385+
sibling.parent.color = .doubleBlack
386+
child = sibling.parent
387+
sibling = child.sibling // can become nill if child is root as parent is nullLeaf
388+
}
389+
//---------------
380390
}
381391
} else { // sibling is red
382-
sibling!.color = .black
392+
sibling.color = .black
383393

384-
if sibling!.isLeftChild { // left case
385-
rightRotate(n: sibling!.parent)
386-
sibling = sibling!.right.left
387-
sibling!.parent.color = .red
394+
if sibling.isLeftChild { // left case
395+
rightRotate(n: sibling.parent)
396+
sibling = sibling.right.left
397+
sibling.parent.color = .red
388398
} else { // right case
389-
leftRotate(n: sibling!.parent)
390-
sibling = sibling!.left.right
391-
sibling!.parent.color = .red
399+
leftRotate(n: sibling.parent)
400+
sibling = sibling.left.right
401+
sibling.parent.color = .red
392402
}
393403
}
394404

395405
// sibling check is here for when child is a nullLeaf and thus does not have a parent.
396406
// child is here as sibling can become nil when child is the root
397-
if (sibling != nil && sibling!.parent === nullLeaf) || (child !== nullLeaf && child.parent === nullLeaf) {
407+
if (sibling.parent === nullLeaf) || (child !== nullLeaf && child.parent === nullLeaf) {
398408
child.color = .black
399409
}
400410
}

0 commit comments

Comments
 (0)