@@ -6,9 +6,10 @@ mutable struct AVLTreeNode{K}
6
6
height:: Int8
7
7
leftChild:: Union{AVLTreeNode{K}, Nothing}
8
8
rightChild:: Union{AVLTreeNode{K}, Nothing}
9
+ subsize:: Int32
9
10
data:: K
10
11
11
- AVLTreeNode {K} (d:: K ) where K = new {K} (1 , nothing , nothing , d)
12
+ AVLTreeNode {K} (d:: K ) where K = new {K} (1 , nothing , nothing , 1 , d)
12
13
end
13
14
14
15
AVLTreeNode (d) = AVLTreeNode {Any} (d)
41
42
# one added the maximum of the height of the left subtree and right subtree
42
43
compute_height (node:: AVLTreeNode ) = 1 + max (get_height (node. leftChild), get_height (node. rightChild))
43
44
45
+ get_subsize (node:: AVLTreeNode_or_null ) = (node == nothing ) ? 0 : node. subsize
46
+
47
+ # compute the subtree size
48
+ function compute_subtree_size (node:: AVLTreeNode_or_null )
49
+ if node == nothing
50
+ return 0
51
+ else
52
+ L = get_subsize (node. leftChild)
53
+ R = get_subsize (node. rightChild)
54
+ return (L + R + 1 )
55
+ end
56
+ end
57
+
44
58
"""
45
59
left_rotate(node_x::AVLTreeNode)
46
60
@@ -53,6 +67,8 @@ function left_rotate(z::AVLTreeNode)
53
67
z. rightChild = α
54
68
z. height = compute_height (z)
55
69
y. height = compute_height (y)
70
+ z. subsize = compute_subtree_size (z)
71
+ y. subsize = compute_subtree_size (y)
56
72
return y
57
73
end
58
74
@@ -68,6 +84,8 @@ function right_rotate(z::AVLTreeNode)
68
84
z. leftChild = α
69
85
z. height = compute_height (z)
70
86
y. height = compute_height (y)
87
+ z. subsize = compute_subtree_size (z)
88
+ y. subsize = compute_subtree_size (y)
71
89
return y
72
90
end
73
91
@@ -118,6 +136,7 @@ function Base.insert!(tree::AVLTree{K}, d::K) where K
118
136
node. rightChild = insert_node (node. rightChild, key)
119
137
end
120
138
139
+ node. subsize = compute_subtree_size (node)
121
140
node. height = compute_height (node)
122
141
balance = get_balance (node)
123
142
@@ -176,7 +195,8 @@ function Base.delete!(tree::AVLTree{K}, d::K) where K
176
195
node. rightChild = delete_node! (node. rightChild, result. data)
177
196
end
178
197
end
179
-
198
+
199
+ node. subsize = compute_subtree_size (node)
180
200
node. height = compute_height (node)
181
201
balance = get_balance (node)
182
202
@@ -197,7 +217,7 @@ function Base.delete!(tree::AVLTree{K}, d::K) where K
197
217
return left_rotate (node)
198
218
end
199
219
end
200
-
220
+
201
221
return node
202
222
end
203
223
@@ -210,17 +230,20 @@ function Base.delete!(tree::AVLTree{K}, d::K) where K
210
230
return tree
211
231
end
212
232
213
- function Base. getindex (tree:: AVLTree{K} , ind) where K
233
+ function Base. getindex (tree:: AVLTree{K} , ind:: Integer ) where K
214
234
@boundscheck (1 <= ind <= tree. count) || throw (BoundsError (" $ind should be in between 1 and $(tree. count) " ))
215
- function traverse_tree_inorder (node:: Union{AVLTreeNode, Nothing} )
235
+ function traverse_tree (node:: AVLTreeNode_or_null , idx )
216
236
if (node != nothing )
217
- left = traverse_tree_inorder (node. leftChild)
218
- right = traverse_tree_inorder (node. rightChild)
219
- append! (push! (left, node. data), right)
220
- else
221
- return K[]
237
+ L = get_subsize (node. leftChild)
238
+ if idx <= L
239
+ return traverse_tree (node. leftChild, idx)
240
+ elseif idx == L + 1
241
+ return node. data
242
+ else
243
+ return traverse_tree (node. rightChild, idx - L - 1 )
244
+ end
222
245
end
223
246
end
224
- arr = traverse_tree_inorder (tree. root)
225
- return @inbounds arr[ind]
226
- end
247
+ value = traverse_tree (tree. root, ind )
248
+ return value
249
+ end
0 commit comments