Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 54f18c8

Browse files
authored
Merge pull request #6 from AryanAhadinia/issue_5
Implement Red-Black Tree
2 parents 2146851 + 0063f6f commit 54f18c8

File tree

3 files changed

+258
-42
lines changed

3 files changed

+258
-42
lines changed
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
import Foundation
2+
3+
class RedBlackTreeNode<T: Comparable> {
4+
var value: T
5+
var isRed: Bool
6+
var left: RedBlackTreeNode?
7+
var right: RedBlackTreeNode?
8+
9+
init(value: T, isRed: Bool, left: RedBlackTreeNode?, right: RedBlackTreeNode?) {
10+
self.value = value
11+
self.isRed = isRed
12+
self.left = left
13+
self.right = right
14+
}
15+
16+
static func isRedNode(node: RedBlackTreeNode?) -> Bool {
17+
if (node == nil) {
18+
return false
19+
}
20+
return node!.isRed
21+
}
22+
23+
func clockwiseRotate() -> RedBlackTreeNode {
24+
let t = self.left!
25+
self.left = t.right
26+
t.right = self
27+
t.isRed = RedBlackTreeNode.isRedNode(node: t.right)
28+
t.right!.isRed = true
29+
return t
30+
}
31+
32+
func counterclockwiseRotate() -> RedBlackTreeNode {
33+
let t = self.right!
34+
self.right = t.left
35+
t.left = self
36+
t.isRed = RedBlackTreeNode.isRedNode(node: t.left)
37+
t.left!.isRed = true
38+
return t
39+
}
40+
41+
func flip() {
42+
self.isRed = !self.isRed
43+
}
44+
45+
func exchange() {
46+
self.flip()
47+
self.left?.flip()
48+
self.right?.flip()
49+
}
50+
51+
func minimum() -> RedBlackTreeNode {
52+
if (self.left == nil) {
53+
return self
54+
}
55+
return self.left!.minimum()
56+
}
57+
58+
func maximum() -> RedBlackTreeNode {
59+
if (self.right == nil) {
60+
return self
61+
}
62+
return self.right!.maximum()
63+
}
64+
65+
func bubbleUp() -> RedBlackTreeNode {
66+
var t = self
67+
if (RedBlackTreeNode.isRedNode(node: t.right)) {
68+
t = t.counterclockwiseRotate()
69+
}
70+
if (RedBlackTreeNode.isRedNode(node: t.left) && RedBlackTreeNode.isRedNode(node: t.left!.left)) {
71+
t = t.clockwiseRotate()
72+
}
73+
if (RedBlackTreeNode.isRedNode(node: t.left) && RedBlackTreeNode.isRedNode(node: t.right)) {
74+
t.exchange()
75+
}
76+
return t
77+
}
78+
79+
func alignLeftNode() -> RedBlackTreeNode {
80+
var t = self
81+
t.exchange()
82+
if (self.right != nil && RedBlackTreeNode.isRedNode(node: t.right!.left)) {
83+
t.right = t.right!.clockwiseRotate()
84+
t = t.counterclockwiseRotate()
85+
t.exchange()
86+
}
87+
return t
88+
}
89+
90+
func alignRightNode() -> RedBlackTreeNode {
91+
var t = self
92+
t.exchange()
93+
if (self.left != nil && RedBlackTreeNode.isRedNode(node: t.left!.left)) {
94+
t = t.clockwiseRotate()
95+
t.exchange()
96+
}
97+
return t
98+
}
99+
100+
func search(value: T) -> RedBlackTreeNode? {
101+
if (self.value == value) {
102+
return self
103+
} else if (self.value < value) {
104+
return self.left?.search(value: value)
105+
} else {
106+
return self.right?.search(value: value)
107+
}
108+
}
109+
110+
func removeMinimum() -> RedBlackTreeNode? {
111+
if (self.left == nil) {
112+
return nil
113+
}
114+
var t = self
115+
if (!RedBlackTreeNode.isRedNode(node: t.left) && !RedBlackTreeNode.isRedNode(node: t.left!.left)) {
116+
t = t.alignLeftNode()
117+
}
118+
t.left = t.left!.removeMinimum()
119+
return t.bubbleUp()
120+
}
121+
122+
func preorderTraversal() -> Array<T> {
123+
var traversal: Array<T> = [self.value]
124+
if (self.left != nil) {
125+
traversal += left!.inorderTraversal()
126+
}
127+
if (self.right != nil) {
128+
traversal += right!.inorderTraversal()
129+
}
130+
return traversal;
131+
}
132+
133+
func inorderTraversal() -> Array<T> {
134+
var traversal: Array<T> = []
135+
if (self.left != nil) {
136+
traversal += left!.inorderTraversal()
137+
}
138+
traversal += [self.value]
139+
if (self.right != nil) {
140+
traversal += right!.inorderTraversal()
141+
}
142+
return traversal;
143+
}
144+
145+
func postorderTraversal() -> Array<T> {
146+
var traversal: Array<T> = []
147+
if (self.left != nil) {
148+
traversal += left!.inorderTraversal()
149+
}
150+
if (self.right != nil) {
151+
traversal += right!.inorderTraversal()
152+
}
153+
traversal += [self.value]
154+
return traversal;
155+
}
156+
}
157+
158+
class RedBlackTree<T: Comparable> {
159+
var root: RedBlackTreeNode<T>? = nil
160+
161+
static func insert(inRoot: RedBlackTreeNode<T>?, val: T) -> RedBlackTreeNode<T>? {
162+
var root = inRoot
163+
if (root == nil) {
164+
return RedBlackTreeNode(value: val, isRed: true, left: nil, right: nil)
165+
}
166+
if (RedBlackTreeNode.isRedNode(node: root!.left) && RedBlackTreeNode.isRedNode(node: root!.right)) {
167+
root!.exchange()
168+
}
169+
if (val == root!.value) {
170+
root!.value = val
171+
} else if (val < root!.value) {
172+
root!.left = insert(inRoot: root!.left, val: val)
173+
} else {
174+
root!.right = insert(inRoot: root!.right, val: val)
175+
}
176+
if (RedBlackTreeNode.isRedNode(node: root!.right)) {
177+
root = root!.counterclockwiseRotate()
178+
}
179+
if (RedBlackTreeNode.isRedNode(node: root!.left) && RedBlackTreeNode.isRedNode(node: root!.left!.left)) {
180+
root = root!.clockwiseRotate()
181+
}
182+
if (RedBlackTreeNode.isRedNode(node: root!.left) && RedBlackTreeNode.isRedNode(node: root!.right)) {
183+
root!.exchange();
184+
}
185+
return root;
186+
}
187+
188+
static func remove(inRoot: RedBlackTreeNode<T>?, val: T) -> RedBlackTreeNode<T>? {
189+
var root = inRoot;
190+
if (val < root!.value) {
191+
if (root!.left != nil && !(RedBlackTreeNode.isRedNode(node: root!.left)) && !(RedBlackTreeNode.isRedNode(node: root!.left!.left))) {
192+
root = root!.alignLeftNode()
193+
}
194+
root!.left = remove(inRoot: root!.left, val: val);
195+
} else {
196+
if (RedBlackTreeNode.isRedNode(node: root!.left)) {
197+
root = root!.clockwiseRotate()
198+
}
199+
if (val == root!.value && root!.right == nil) {
200+
return nil
201+
}
202+
if (root!.right != nil && !(RedBlackTreeNode.isRedNode(node: root!.right)) && !(RedBlackTreeNode.isRedNode(node: root!.right!.left))) {
203+
root = root!.alignRightNode()
204+
}
205+
if (val == root!.value) {
206+
root!.value = root!.right!.minimum().value
207+
root!.right = root!.right!.removeMinimum()
208+
} else {
209+
root!.right = remove(inRoot: root!.right, val: val);
210+
}
211+
}
212+
return root!.bubbleUp()
213+
}
214+
215+
func insert(value: T) {
216+
root = RedBlackTree.insert(inRoot: root, val: value)
217+
if (root != nil) {
218+
root!.isRed = false
219+
}
220+
}
221+
222+
func remove(value: T) {
223+
if (search(value: value) == nil) {
224+
return
225+
}
226+
root = RedBlackTree.remove(inRoot: root, val: value)
227+
if (root != nil) {
228+
root!.isRed = false
229+
}
230+
}
231+
232+
func search(value: T) -> RedBlackTreeNode<T>? {
233+
return root?.search(value: value)
234+
}
235+
236+
func preorderTraversal() -> Array<T> {
237+
if (root == nil) {
238+
return Array<T>()
239+
}
240+
return root!.preorderTraversal()
241+
}
242+
243+
func inorderTraversal() -> Array<T> {
244+
if (root == nil) {
245+
return Array<T>()
246+
}
247+
return root!.inorderTraversal()
248+
}
249+
250+
func postorderTraversal() -> Array<T> {
251+
if (root == nil) {
252+
return Array<T>()
253+
}
254+
return root!.postorderTraversal()
255+
}
256+
}

‎Data Structures.playground/Pages/Red-Black Tree.xcplaygroundpage/Contents.swift‎

Lines changed: 0 additions & 40 deletions
This file was deleted.

‎README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# swift-algorithms-data-structs [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome)
22

3-
[![Language](https://img.shields.io/badge/language-Swift_5.0-orange.svg)]()
3+
[![Language](https://img.shields.io/badge/language-Swift_5.3-orange.svg)]()
44
[![License](https://img.shields.io/badge/license-MIT-blue.svg)]()
55

6-
**Last Update: 27/April/2019.**
6+
**Last Update: 18/July/2021.**
77

88
![](https://github.com/jVirus/swift-algorithms-data-structs/blob/master/cover-algo-datastruct.png)
99

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /