-
Notifications
You must be signed in to change notification settings - Fork 2
/
RedBlackTree.swift
138 lines (106 loc) · 2.96 KB
/
RedBlackTree.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//
// RedBlackTree.swift
// AdvancedDataStructures
//
// Created by Vladislav Fitc on 01.03.17.
// Copyright © 2017 Fitc. All rights reserved.
//
import Foundation
enum Color {
case red, black
}
/**
- Root and leaves are black
- Red node has black parent
- All paths from each node contain the same quantity of black nodes
– Black node may have black parent
*/
final class RedBlackTree<Element: Comparable & Equatable>: BinaryTreeWithParent {
var element: Element
var left: RedBlackTree?
var right: RedBlackTree?
weak var parent: RedBlackTree?
var color: Color
init(element: Element, left: RedBlackTree?, right: RedBlackTree?) {
self.element = element
self.left = left
self.right = right
self.parent = nil
self.color = .black
}
init(element: Element, left: RedBlackTree?, right: RedBlackTree?, parent: RedBlackTree?) {
self.element = element
self.left = left
self.right = right
self.color = .black
self.parent = parent
}
init(element: Element, left: RedBlackTree?, right: RedBlackTree?, color: Color, parent: RedBlackTree? = .none) {
self.element = element
self.left = left
self.right = right
self.color = color
self.parent = parent
}
var nodeDescription: String {
return "\(element) [\(color)]"
}
func with(parent: RedBlackTree?) -> RedBlackTree {
self.parent = parent
return self
}
func with(color: Color) -> RedBlackTree {
self.color = color
return self
}
func with(left: RedBlackTree?) -> RedBlackTree {
self.left = left
return self
}
func with(right: RedBlackTree?) -> RedBlackTree {
self.right = right
return self
}
func with(element: Element) -> RedBlackTree {
self.element = element
return self
}
}
extension RedBlackTree {
func insert(_ element: Element) {
let currentElement = self.element
var shouldCheckBalance: Bool = false
var uncleColor: Color = .black
if element > currentElement {
if let right = self.right {
right.insert(element)
} else {
shouldCheckBalance = color == .red
uncleColor = left?.color ?? .black
right = RedBlackTree(element: element, left: .none, right: .none, color: .red, parent: self)
}
} else if element < currentElement {
if let left = self.left {
left.insert(element)
} else {
shouldCheckBalance = color == .red
uncleColor = right?.color ?? .black
left = RedBlackTree(element: element, left: .none, right: .none, color: .red, parent: self)
}
} else {
self.element = element
}
guard shouldCheckBalance else { return }
switch uncleColor {
case .red:
self.color = .black
self.brother?.color = .black
self.parent?.color = .red
case .black:
break
}
}
func remove(_ element: Element) {
//TODO:
}
}