1
1
package structures
2
2
3
+ import java.util.LinkedList
4
+
3
5
/* *
4
6
*
5
- * data structure: binary tree
7
+ * Binary tree consists of nodes each of which has a maximum of two children.
8
+ *
9
+ * Child nodes satisfy the following requirements:
10
+ *
11
+ * - the left child is less than the parent
12
+ * - right child is larger than parent
6
13
*
7
- * description: consists of nodes, each of which has a maximum of two children,
8
- * child nodes satisfy the following requirements:
9
- * - the left child is less than the parent;
10
- * - right child is larger than parent;
14
+ * Hint: the worst time may be O(n) because the situation is possible when the elements follow each other 1,2,3,4...
15
+ * and the tree takes the following form:
11
16
*
12
- * average search time: log(n)
13
- * worst search time: n
14
- * because the situation is possible when the elements follow each other 1,2,3,4... and the tree takes the following form:
15
17
* 1
16
18
* \
17
19
* 2
18
20
* \
19
21
* 3
20
22
* \
21
23
* 4
22
- * the same complexity is true for adding and removing nodes
23
24
*
24
25
*/
25
26
26
- class BinaryTree {
27
+ class BinaryTree < T : Comparable < T >> {
27
28
28
- /* *
29
- * binary tree root
30
- */
31
- private var root : Node ? = null
29
+ private var root : Node < T > ? = null
30
+
31
+ val isEmpty : Boolean
32
+ get() = root = = null
32
33
33
34
/* *
34
- * adds a new element [value] to the tree
35
+ * Complexity:
36
+ * worst time: O(n), read the hint in the description
37
+ * best time: O(log(n))
38
+ * average time: O(log(n))
35
39
*/
36
- fun add (value : Int ) {
37
- fun addRec (current : Node ? , value : Int ) : Node {
40
+ fun add (value : T ) {
41
+ fun addRecursive (current : Node < T > ? , value : T ) : Node < T > {
38
42
if (current == null ) {
39
43
return Node (value)
40
44
}
41
45
if (value < current.value()) {
42
- current.changeLeft(addRec (current.leftNode(), value))
46
+ current.changeLeft(addRecursive (current.leftNode(), value))
43
47
} else if (value > current.value()) {
44
- current.changeRight(addRec (current.rightNode(), value))
48
+ current.changeRight(addRecursive (current.rightNode(), value))
45
49
}
46
50
return current
47
51
}
48
52
49
- root = addRec (root, value)
53
+ root = addRecursive (root, value)
50
54
}
51
55
52
56
/* *
53
- * checks the tree for emptiness and returns true if the tree does not contain any nodes
57
+ * Complexity:
58
+ * worst time: O(n), read the hint in the description
59
+ * best time: O(1)
60
+ * average time: O(log(n))
54
61
*/
55
- fun isEmpty () = root == null
56
-
57
- /* *
58
- * removes an element [value] from the tree
59
- */
60
- fun remove (value : Int ) {
61
- fun smallestValue (root : Node ) : Int {
62
- return if (root.leftNode() == null ) root.value() else smallestValue(root.leftNode()!! )
62
+ fun remove (value : T ) {
63
+ fun smallestValue (root : Node <T >): T {
64
+ val leftNode = root.leftNode()
65
+ if (leftNode == = null ) return root.value()
66
+ return smallestValue(leftNode)
63
67
}
64
68
65
- fun removeRec (current : Node ? , value : Int ) : Node ? {
69
+ fun removeRecursive (current : Node < T > ? , value : T ) : Node < T > ? {
66
70
if (current == null ) {
67
71
return null
68
72
}
@@ -80,180 +84,164 @@ class BinaryTree {
80
84
81
85
val smallestValue = smallestValue(current.rightNode()!! )
82
86
current.changeValue(smallestValue)
83
- current.changeRight(removeRec (current.rightNode(), smallestValue))
87
+ current.changeRight(removeRecursive (current.rightNode(), smallestValue))
84
88
return current
85
89
}
86
90
87
91
if (value < current.value()) {
88
- current.changeLeft(removeRec (current.leftNode(), value))
92
+ current.changeLeft(removeRecursive (current.leftNode(), value))
89
93
} else {
90
- current.changeRight(removeRec (current.rightNode(), value))
94
+ current.changeRight(removeRecursive (current.rightNode(), value))
91
95
}
92
96
93
97
return current
94
98
}
95
99
96
- root = removeRec (root, value)
100
+ root = removeRecursive (root, value)
97
101
}
98
102
99
103
/* *
100
- * checks for the existence of an element [value] in the tree, returns true if the element exists
104
+ * Complexity:
105
+ * worst time: O(n), read the hint in the description
106
+ * best time: O(1)
107
+ * average time: O(log(n))
101
108
*/
102
- fun contains (value : Int ) : Boolean {
103
- fun containsRec (current : Node ? , value : Int ) : Boolean {
109
+ fun contains (value : T ) : Boolean {
110
+ fun containsRecursive (current : Node < T > ? , value : T ) : Boolean {
104
111
if (current == null ) {
105
112
return false
106
113
}
107
114
if (value == current.value()) {
108
115
return true
109
116
}
110
117
return if (value < current.value()) {
111
- containsRec (current.leftNode(), value)
118
+ containsRecursive (current.leftNode(), value)
112
119
} else {
113
- containsRec (current.rightNode(), value)
120
+ containsRecursive (current.rightNode(), value)
114
121
}
115
122
}
116
123
117
- return containsRec (root, value)
124
+ return containsRecursive (root, value)
118
125
}
119
126
120
127
/* *
121
- * traversal of the binary tree in depth
122
128
*
123
- * first the left child, then the parent, then the right child
129
+ * Traversal of the binary tree in depth
130
+ *
131
+ * order: the left child, the parent, the right child
124
132
*
125
- * @return returns the elements of the tree
126
133
*/
127
- fun traverseInOrder (): List <Int > {
128
- fun traverseInOrderRec (node : Node ? , nodes : MutableList <Int >) {
134
+ fun traverseInOrder (): List <T > {
135
+ fun traverseInOrderRecursive (node : Node < T > ? , nodes : MutableList <T >) {
129
136
if (node != null ) {
130
- traverseInOrderRec (node.leftNode(), nodes)
137
+ traverseInOrderRecursive (node.leftNode(), nodes)
131
138
nodes.add(node.value())
132
- traverseInOrderRec (node.rightNode(), nodes)
139
+ traverseInOrderRecursive (node.rightNode(), nodes)
133
140
}
134
141
}
135
142
136
- return mutableListOf<Int >(). apply {
137
- traverseInOrderRec (root, this )
138
- }
143
+ val nodes = mutableListOf<T >()
144
+ traverseInOrderRecursive (root, nodes )
145
+ return nodes
139
146
}
140
147
141
148
/* *
142
- * traversal of the binary tree in depth
143
149
*
144
- * parent first, then left and right children
150
+ * Traversal of the binary tree in depth
151
+ *
152
+ * order: the parent, the left child, the right child
145
153
*
146
- * @return returns the elements of the tree
147
154
*/
148
- fun traversePreOrder (): List <Int > {
149
- fun traversePreOrderRec (node : Node ? , nodes : MutableList <Int >) {
155
+ fun traversePreOrder (): List <T > {
156
+ fun traversePreOrderRecursive (node : Node < T > ? , nodes : MutableList <T >) {
150
157
if (node != null ) {
151
158
nodes.add(node.value())
152
- traversePreOrderRec (node.leftNode(), nodes)
153
- traversePreOrderRec (node.rightNode(), nodes)
159
+ traversePreOrderRecursive (node.leftNode(), nodes)
160
+ traversePreOrderRecursive (node.rightNode(), nodes)
154
161
}
155
162
}
156
163
157
- return mutableListOf<Int >(). apply {
158
- traversePreOrderRec (root, this )
159
- }
164
+ val nodes = mutableListOf<T >()
165
+ traversePreOrderRecursive (root, nodes )
166
+ return nodes
160
167
}
161
168
162
169
/* *
163
- * traversal of the binary tree in depth
164
170
*
165
- * first the left and right children, then the parent
171
+ * Traversal of the binary tree in depth
172
+ *
173
+ * order: the left child, the right child, the parent
166
174
*
167
- * @return returns the elements of the tree
168
175
*/
169
- fun traversePostOrder (): List <Int > {
170
- fun traversePostOrderRec (node : Node ? , nodes : MutableList <Int >) {
176
+ fun traversePostOrder (): List <T > {
177
+ fun traversePostOrderRec (node : Node < T > ? , nodes : MutableList <T >) {
171
178
if (node != null ) {
172
179
traversePostOrderRec(node.leftNode(), nodes)
173
180
traversePostOrderRec(node.rightNode(), nodes)
174
181
nodes.add(node.value())
175
182
}
176
183
}
177
184
178
- return mutableListOf<Int >(). apply {
179
- traversePostOrderRec(root, this )
180
- }
185
+ val nodes = mutableListOf<T >()
186
+ traversePostOrderRec(root, nodes )
187
+ return nodes
181
188
}
182
189
183
190
/* *
184
- * traversal of the binary tree in breadth
185
191
*
186
- * uses an additional data structure - a queue into which new tree
192
+ * Traversal of the binary tree in breadth uses an additional data structure - a queue into which new tree
193
+ *
187
194
* nodes are added until the last node is added
188
195
*
189
- * @return returns the elements of the tree
190
196
*/
191
- fun traverseLevelOrder (): List <Int > {
192
- val root = this . root ? : return listOf ()
197
+ fun traverseLevelOrder (): List <T > {
198
+ val current = root ? : return emptyList ()
193
199
194
- val queue = java.util. LinkedList <Node >()
195
- queue.add(root )
200
+ val queue = LinkedList <Node < T > >()
201
+ queue.add(current )
196
202
197
- val items = mutableListOf<Int >()
203
+ val nodeValues = mutableListOf<T >()
198
204
199
205
while (queue.isNotEmpty()) {
200
- val node = queue.remove()
201
- items.add(node.value())
206
+ val node = queue.removeFirst()
202
207
203
- node.leftNode()?.let (queue::add)
204
- node.rightNode()?.let (queue::add)
208
+ nodeValues.add(node.value())
209
+
210
+ val leftNode = node.leftNode()
211
+ if (leftNode != null ) {
212
+ queue.add(leftNode)
213
+ }
214
+
215
+ val rightNode = node.rightNode()
216
+ if (rightNode != null ) {
217
+ queue.add(rightNode)
218
+ }
205
219
}
206
220
207
- return items
221
+ return nodeValues
208
222
}
209
223
210
- }
224
+ class Node <T >(
225
+ private var value : T ,
226
+ private var left : Node <T >? = null ,
227
+ private var right : Node <T >? = null
228
+ ) {
211
229
212
- /* *
213
- * represents a tree node
214
- *
215
- * @property value - node value
216
- * @property left - left child node
217
- * @property right - right child node
218
- */
219
- class Node (
220
- private var value : Int ,
221
- private var left : Node ? = null ,
222
- private var right : Node ? = null
223
- ) {
224
- /* *
225
- * returns the value of the node
226
- */
227
- fun value () = value
230
+ fun value () = value
231
+ fun changeValue (newValue : T ) {
232
+ value = newValue
233
+ }
228
234
229
- /* *
230
- * changes the value of a node
231
- */
232
- fun changeValue (value : Int ) {
233
- this .value = value
234
- }
235
+ fun leftNode () = left
236
+ fun changeLeft (node : Node <T >? ) {
237
+ left = node
238
+ }
235
239
236
- /* *
237
- * changes the left child node
238
- */
239
- fun changeLeft (left : Node ? ) {
240
- this .left = left
241
- }
240
+ fun rightNode () = right
241
+ fun changeRight (node : Node <T >? ) {
242
+ right = node
243
+ }
242
244
243
- /* *
244
- * changes the right child node
245
- */
246
- fun changeRight (right : Node ? ) {
247
- this .right = right
248
245
}
249
246
250
- /* *
251
- * returns the left child node
252
- */
253
- fun leftNode () = left
254
-
255
- /* *
256
- * returns the right child node
257
- */
258
- fun rightNode () = right
259
247
}
0 commit comments