Skip to content

Commit de3bc6e

Browse files
committed
Implement Red Black Tree
1 parent 93a04e1 commit de3bc6e

File tree

8 files changed

+96
-8
lines changed

8 files changed

+96
-8
lines changed

src/main/kotlin/ru/romanow/algorithms/RedBlackTree.kt

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,69 @@ class RedBlackTree {
1818
return null
1919
}
2020

21+
fun put(key: Int, value: Int = key) {
22+
root = insert(root, key, value)
23+
root?.color = false
24+
}
25+
26+
fun remove(key: Int) {
27+
28+
}
29+
30+
private fun insert(n: TreeNode?, key: Int, value: Int): TreeNode {
31+
var node = n ?: return TreeNode(key, value)
32+
when {
33+
key < node.key -> node.left = insert(node.left, key, value)
34+
key > node.key -> node.right = insert(node.right, key, value)
35+
else -> node.value = value
36+
}
37+
38+
if (isRed(node.right) && !isRed(node.left)) {
39+
node = rotateLeft(node)
40+
}
41+
if (isRed(node.left) && isRed(node.left?.left)) {
42+
node = rotateRight(node)
43+
}
44+
if (isRed(node.left) && isRed(node.right)) {
45+
flipColors(node)
46+
}
47+
48+
return node
49+
}
50+
51+
private fun isRed(node: TreeNode?): Boolean {
52+
return node?.color == true
53+
}
54+
55+
private fun rotateLeft(node: TreeNode): TreeNode {
56+
val right = node.right!!
57+
node.right = right.left
58+
right.left = node
59+
right.color = node.color
60+
node.color = true
61+
return right
62+
}
63+
64+
private fun rotateRight(node: TreeNode): TreeNode {
65+
val left = node.left!!
66+
node.left = left.right
67+
left.right = node
68+
left.color = node.color
69+
node.color = true
70+
return left
71+
}
72+
73+
private fun flipColors(node: TreeNode) {
74+
node.color = true
75+
node.left?.color = false
76+
node.right?.color = false
77+
}
78+
2179
internal class TreeNode(
2280
override var key: Int,
2381
override var value: Int,
2482
var color: Boolean = false,
25-
override var left: TreeNode?,
26-
override var right: TreeNode?
83+
override var left: TreeNode? = null,
84+
override var right: TreeNode? = null
2785
) : TNode<TreeNode>
2886
}

src/test/kotlin/ru/romanow/algorithms/BinarySearchListTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class BinarySearchListTest {
1212

1313
@ArgumentsSource(ValueProvider::class)
1414
@ParameterizedTest(name = "#{index} – Search {1} in tree {0}")
15-
fun flatten(list: List<Int>, target: Int, result: Int?) {
15+
fun test(list: List<Int>, target: Int, result: Int?) {
1616
val obj = BinarySearchList()
1717
assertThat(obj.find(list, target)).isEqualTo(result)
1818
}

src/test/kotlin/ru/romanow/algorithms/BinarySearchTreeTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class BinarySearchTreeTest {
1212

1313
@ArgumentsSource(ValueProvider::class)
1414
@ParameterizedTest(name = "#{index} – Search {1} in tree {0}")
15-
fun flatten(items: List<Int>, key: Int, result: Int?) {
15+
fun test(items: List<Int>, key: Int, result: Int?) {
1616
val obj = BinarySearchTree()
1717
items.forEach { obj.put(it) }
1818
assertThat(obj.get(key)).isEqualTo(result)

src/test/kotlin/ru/romanow/algorithms/BreadthFirstSearchTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class BreadthFirstSearchTest {
1313

1414
@ArgumentsSource(ValueProvider::class)
1515
@ParameterizedTest(name = "#{index} – Bfs {0} is {1}")
16-
fun flatten(items: List<Int?>, result: List<Int>) {
16+
fun test(items: List<Int?>, result: List<Int>) {
1717
val root = buildTreeFromList(items)
1818
// printTree(root)
1919

src/test/kotlin/ru/romanow/algorithms/InOrderDeepFirstSearchTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class InOrderDeepFirstSearchTest {
1313

1414
@ArgumentsSource(ValueProvider::class)
1515
@ParameterizedTest(name = "#{index} – In-order dfs {0} is {1}")
16-
fun flatten(items: List<Int?>, result: List<Int>) {
16+
fun test(items: List<Int?>, result: List<Int>) {
1717
val root = buildTreeFromList(items)
1818
// printTree(root)
1919

src/test/kotlin/ru/romanow/algorithms/PostOrderDeepFirstSearchTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class PostOrderDeepFirstSearchTest {
1313

1414
@ArgumentsSource(ValueProvider::class)
1515
@ParameterizedTest(name = "#{index} – Post-order dfs {0} is {1}")
16-
fun flatten(items: List<Int?>, result: List<Int>) {
16+
fun test(items: List<Int?>, result: List<Int>) {
1717
val root = buildTreeFromList(items)
1818
// printTree(root)
1919

src/test/kotlin/ru/romanow/algorithms/PreOrderDeepFirstSearchTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class PreOrderDeepFirstSearchTest {
1313

1414
@ArgumentsSource(ValueProvider::class)
1515
@ParameterizedTest(name = "#{index} – Pre-order dfs {0} is {1}")
16-
fun flatten(items: List<Int?>, result: List<Int>) {
16+
fun test(items: List<Int?>, result: List<Int>) {
1717
val root = buildTreeFromList(items)
1818
// printTree(root)
1919

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package ru.romanow.algorithms
2+
3+
import org.assertj.core.api.Assertions.assertThat
4+
import org.junit.jupiter.api.extension.ExtensionContext
5+
import org.junit.jupiter.params.ParameterizedTest
6+
import org.junit.jupiter.params.provider.Arguments
7+
import org.junit.jupiter.params.provider.ArgumentsProvider
8+
import org.junit.jupiter.params.provider.ArgumentsSource
9+
import java.util.stream.Stream
10+
11+
class RedBlackTreeTest {
12+
13+
@ArgumentsSource(ValueProvider::class)
14+
@ParameterizedTest(name = "#{index} – Search {1} in tree {0}")
15+
fun test(items: List<Int>, key: Int, result: Int?) {
16+
val obj = RedBlackTree()
17+
items.forEach { obj.put(it) }
18+
assertThat(obj.get(key)).isEqualTo(result)
19+
obj.remove(key)
20+
assertThat(obj.get(key)).isNull()
21+
}
22+
23+
internal class ValueProvider : ArgumentsProvider {
24+
override fun provideArguments(context: ExtensionContext): Stream<Arguments> =
25+
Stream.of(
26+
Arguments.of(listOf(10, 5, 15, 3, 7, 12, 20), 20, 20),
27+
Arguments.of(listOf(10, 5, 15, 3, 7, 12, 20), 0, null)
28+
)
29+
}
30+
}

0 commit comments

Comments
 (0)