Skip to content

Commit c10c749

Browse files
committed
Add tree traversal
1 parent 5b2f23b commit c10c749

File tree

6 files changed

+118
-21
lines changed

6 files changed

+118
-21
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package ru.romanow.algorithms
2+
3+
import ru.romanow.models.TreeNode
4+
5+
class BinarySearchTree {
6+
fun find(root: TreeNode?, target: Int): TreeNode? {
7+
return when {
8+
root == null -> null
9+
target == root.value -> root
10+
target < root.value -> find(root.left, target)
11+
else -> find(root.right, target)
12+
}
13+
}
14+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package ru.romanow.algorithms
2+
3+
import ru.romanow.models.TreeNode
4+
import ru.romanow.models.buildTreeFromList
5+
import java.util.*
6+
7+
fun main() {
8+
val root = buildTreeFromList(listOf(10, 5, 15, 3, 7, 12, 20))
9+
printTree(root)
10+
preOrder(root)
11+
println()
12+
inOrder(root)
13+
println()
14+
postOrder(root)
15+
println()
16+
bfs(root)
17+
}
18+
19+
private fun printTree(node: TreeNode?, level: Int = 0) {
20+
if (node == null) return
21+
print(" ".repeat(level))
22+
println("├─ ${node.value}")
23+
printTree(node.left, level + 1)
24+
printTree(node.right, level + 1)
25+
}
26+
27+
private fun preOrder(node: TreeNode?) {
28+
if (node == null) {
29+
return
30+
}
31+
print("${node.value} ")
32+
preOrder(node.left)
33+
preOrder(node.right)
34+
}
35+
36+
private fun inOrder(node: TreeNode?) {
37+
if (node == null) {
38+
return
39+
}
40+
inOrder(node.left)
41+
print("${node.value} ")
42+
inOrder(node.right)
43+
}
44+
45+
private fun postOrder(node: TreeNode?) {
46+
if (node == null) {
47+
return
48+
}
49+
postOrder(node.left)
50+
postOrder(node.right)
51+
print("${node.value} ")
52+
}
53+
54+
private fun bfs(root: TreeNode?) {
55+
if (root == null) {
56+
return
57+
}
58+
59+
val queue = LinkedList<TreeNode>()
60+
queue.add(root)
61+
62+
while (queue.isNotEmpty()) {
63+
val node = queue.poll()
64+
print("${node.value} ")
65+
66+
node.left?.let { queue.add(it) }
67+
node.right?.let { queue.add(it) }
68+
}
69+
}

src/main/kotlin/ru/romanow/models/TreeNode.kt

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,10 @@
11
package ru.romanow.models
22

3-
import java.util.LinkedList
3+
import java.util.*
44

5-
class TreeNode {
6-
var value: Int? = null
5+
data class TreeNode(var value: Int) {
76
var left: TreeNode? = null
87
var right: TreeNode? = null
9-
10-
constructor(value: Int?) {
11-
this.value = value
12-
}
13-
14-
constructor(value: Int?, left: TreeNode?, right: TreeNode?) {
15-
this.value = value
16-
this.left = left
17-
this.right = right
18-
}
19-
20-
override fun toString(): String {
21-
return "TreeNode(value=$value, left=${left?.value}, right=${right?.value})"
22-
}
238
}
249

2510
fun buildListFromTree(root: TreeNode?): List<Int?> {
@@ -41,10 +26,10 @@ fun buildListFromTree(root: TreeNode?): List<Int?> {
4126
return list
4227
}
4328

44-
fun buildTreeFromList(values: List<Int?>, index: Int): TreeNode? {
29+
fun buildTreeFromList(values: List<Int?>, index: Int = 0): TreeNode? {
4530
var node: TreeNode? = null
4631
if (index < values.size && values[index] != null) {
47-
node = TreeNode(value = values[index])
32+
node = TreeNode(value = values[index]!!)
4833
node.left = buildTreeFromList(values, 2 * index + 1)
4934
node.right = buildTreeFromList(values, 2 * index + 2)
5035
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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 ru.romanow.models.buildTreeFromList
10+
import java.util.stream.Stream
11+
12+
class BinarySearchTreeTest {
13+
14+
@ArgumentsSource(ValueProvider::class)
15+
@ParameterizedTest(name = "#{index} – Search {1} in tree {0}")
16+
fun flatten(items: List<Int?>, target: Int, result: Int?) {
17+
val root = buildTreeFromList(items)
18+
val obj = BinarySearchTree()
19+
assertThat(obj.find(root, target)?.value).isEqualTo(result)
20+
}
21+
22+
internal class ValueProvider : ArgumentsProvider {
23+
override fun provideArguments(context: ExtensionContext): Stream<Arguments> =
24+
Stream.of(
25+
Arguments.of(listOf(10, 5, 15, 3, 7, 12, 20), 20, 20),
26+
Arguments.of(listOf(10, 5, 15, 3, 7, 12, 20), 0, null)
27+
)
28+
}
29+
}

src/test/kotlin/ru/romanow/medium/DeleteNodeInABalancedSearchTreeTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class DeleteNodeInABalancedSearchTreeTest {
1616
@ParameterizedTest(name = "#{index} – Tree {0} after removing key {1} is {2}")
1717
fun deleteNode(values: List<Int?>, key: Int, expectedResult: List<Int?>) {
1818
val obj = DeleteNodeInABalancedSearchTree()
19-
val root = buildTreeFromList(values, 0)
19+
val root = buildTreeFromList(values)
2020
val result = buildListFromTree(obj.deleteNode(root, key))
2121
assertThat(result).isEqualTo(expectedResult)
2222
}

src/test/kotlin/ru/romanow/medium/FlattenBinaryTreeToLinkedListTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class FlattenBinaryTreeToLinkedListTest {
1515
@ArgumentsSource(ValueProvider::class)
1616
@ParameterizedTest(name = "#{index} – Binary tree {0} flatten into {1}")
1717
fun flatten(items: List<Int?>, result: List<Int>) {
18-
val root = buildTreeFromList(items, 0)
18+
val root = buildTreeFromList(items)
1919

2020
val obj = FlattenBinaryTreeToLinkedList()
2121
obj.flatten(root)

0 commit comments

Comments
 (0)