1
+ # it has unique keys
2
+ # leftChild has keys which are less than the node
3
+ # rightChild has keys which are greater than the node
4
+ # height stores the height of the subtree.
5
+ mutable struct AVLTreeNode{K}
6
+ height:: Int8
7
+ leftChild:: Union{AVLTreeNode{K}, Nothing}
8
+ rightChild:: Union{AVLTreeNode{K}, Nothing}
9
+ subsize:: Int32
10
+ data:: K
11
+
12
+ AVLTreeNode {K} (d:: K ) where K = new {K} (1 , nothing , nothing , 1 , d)
13
+ end
14
+
15
+ AVLTreeNode (d) = AVLTreeNode {Any} (d)
16
+
17
+ AVLTreeNode_or_null{T} = Union{AVLTreeNode{T}, Nothing}
18
+
19
+ mutable struct AVLTree{T}
20
+ root:: AVLTreeNode_or_null{T}
21
+ count:: Int
22
+
23
+ AVLTree {T} () where T = new {T} (nothing , 0 )
24
+ end
25
+
26
+ AVLTree () = AVLTree {Any} ()
27
+
28
+ Base. length (tree:: AVLTree ) = tree. count
29
+
30
+ get_height (node:: Union{AVLTreeNode, Nothing} ) = (node == nothing ) ? 0 : node. height
31
+
32
+ # balance is the difference of height between leftChild and rightChild of a node.
33
+ function get_balance (node:: Union{AVLTreeNode, Nothing} )
34
+ if node == nothing
35
+ return 0
36
+ else
37
+ return get_height (node. leftChild) - get_height (node. rightChild)
38
+ end
39
+ end
40
+
41
+ # computes the height of the subtree, which basically is
42
+ # one added the maximum of the height of the left subtree and right subtree
43
+ compute_height (node:: AVLTreeNode ) = 1 + max (get_height (node. leftChild), get_height (node. rightChild))
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
+
58
+ """
59
+ left_rotate(node_x::AVLTreeNode)
60
+
61
+ Performs a left-rotation on `node_x`, updates height of the nodes, and returns the rotated node.
62
+ """
63
+ function left_rotate (z:: AVLTreeNode )
64
+ y = z. rightChild
65
+ α = y. leftChild
66
+ y. leftChild = z
67
+ z. rightChild = α
68
+ z. height = compute_height (z)
69
+ y. height = compute_height (y)
70
+ z. subsize = compute_subtree_size (z)
71
+ y. subsize = compute_subtree_size (y)
72
+ return y
73
+ end
74
+
75
+ """
76
+ right_rotate(node_x::AVLTreeNode)
77
+
78
+ Performs a right-rotation on `node_x`, updates height of the nodes, and returns the rotated node.
79
+ """
80
+ function right_rotate (z:: AVLTreeNode )
81
+ y = z. leftChild
82
+ α = y. rightChild
83
+ y. rightChild = z
84
+ z. leftChild = α
85
+ z. height = compute_height (z)
86
+ y. height = compute_height (y)
87
+ z. subsize = compute_subtree_size (z)
88
+ y. subsize = compute_subtree_size (y)
89
+ return y
90
+ end
91
+
92
+ """
93
+ minimum_node(tree::AVLTree, node::AVLTreeNode)
94
+
95
+ Returns the AVLTreeNode with minimum value in subtree of `node`.
96
+ """
97
+ function minimum_node (node:: Union{AVLTreeNode, Nothing} )
98
+ while node != nothing && node. leftChild != nothing
99
+ node = node. leftChild
100
+ end
101
+ return node
102
+ end
103
+
104
+ function search_node (tree:: AVLTree{K} , d:: K ) where K
105
+ prev = nothing
106
+ node = tree. root
107
+ while node != nothing && node. data != nothing && node. data != d
108
+
109
+ prev = node
110
+ if d < node. data
111
+ node = node. leftChild
112
+ else
113
+ node = node. rightChild
114
+ end
115
+ end
116
+
117
+ return (node == nothing ) ? prev : node
118
+ end
119
+
120
+ function Base. haskey (tree:: AVLTree{K} , d:: K ) where K
121
+ (tree. root == nothing ) && return false
122
+ node = search_node (tree, d)
123
+ return (node. data == d)
124
+ end
125
+
126
+ Base. in (key, tree:: AVLTree ) = haskey (tree, key)
127
+
128
+ function Base. insert! (tree:: AVLTree{K} , d:: K ) where K
129
+
130
+ function insert_node (node:: Union{AVLTreeNode, Nothing} , key)
131
+ if node == nothing
132
+ return AVLTreeNode {K} (key)
133
+ elseif key < node. data
134
+ node. leftChild = insert_node (node. leftChild, key)
135
+ else
136
+ node. rightChild = insert_node (node. rightChild, key)
137
+ end
138
+
139
+ node. subsize = compute_subtree_size (node)
140
+ node. height = compute_height (node)
141
+ balance = get_balance (node)
142
+
143
+ if balance > 1
144
+ if key < node. leftChild. data
145
+ return right_rotate (node)
146
+ else
147
+ node. leftChild = left_rotate (node. leftChild)
148
+ return right_rotate (node)
149
+ end
150
+ end
151
+
152
+ if balance < - 1
153
+ if key > node. rightChild. data
154
+ return left_rotate (node)
155
+ else
156
+ node. rightChild = right_rotate (node. rightChild)
157
+ return left_rotate (node)
158
+ end
159
+ end
160
+
161
+ return node
162
+ end
163
+
164
+ haskey (tree, d) && return tree
165
+
166
+ tree. root = insert_node (tree. root, d)
167
+ tree. count += 1
168
+ return tree
169
+ end
170
+
171
+ function Base. push! (tree:: AVLTree{K} , key0) where K
172
+ key = convert (K, key0)
173
+ insert! (tree, key)
174
+ end
175
+
176
+ function Base. delete! (tree:: AVLTree{K} , d:: K ) where K
177
+
178
+ function delete_node! (node:: Union{AVLTreeNode, Nothing} , key)
179
+ if key < node. data
180
+ node. leftChild = delete_node! (node. leftChild, key)
181
+ elseif key > node. data
182
+ node. rightChild = delete_node! (node. rightChild, key)
183
+ else
184
+ if node. leftChild == nothing
185
+ result = node. rightChild
186
+ return result
187
+ elseif node. rightChild == nothing
188
+ result = node. leftChild
189
+ return result
190
+ else
191
+ result = minimum_node (node. rightChild)
192
+ node. data = result. data
193
+ node. rightChild = delete_node! (node. rightChild, result. data)
194
+ end
195
+ end
196
+
197
+ node. subsize = compute_subtree_size (node)
198
+ node. height = compute_height (node)
199
+ balance = get_balance (node)
200
+
201
+ if balance > 1
202
+ if get_balance (node. leftChild) >= 0
203
+ return right_rotate (node)
204
+ else
205
+ node. leftChild = left_rotate (node. leftChild)
206
+ return right_rotate (node)
207
+ end
208
+ end
209
+
210
+ if balance < - 1
211
+ if get_balance (node. rightChild) <= 0
212
+ return left_rotate (node)
213
+ else
214
+ node. rightChild = right_rotate (node. rightChild)
215
+ return left_rotate (node)
216
+ end
217
+ end
218
+
219
+ return node
220
+ end
221
+
222
+ # if the key is not in the tree, do nothing and return the tree
223
+ ! haskey (tree, d) && return tree
224
+
225
+ # if the key is present, delete it from the tree
226
+ tree. root = delete_node! (tree. root, d)
227
+ tree. count -= 1
228
+ return tree
229
+ end
230
+
231
+ """
232
+ sorted_rank(tree::AVLTree, key)
233
+
234
+ Returns the rank of `key` present in the `tree`, if it present. A KeyError is thrown if `key` is not present.
235
+ """
236
+ function sorted_rank (tree:: AVLTree{K} , key:: K ) where K
237
+ ! haskey (tree, key) && throw (KeyError (key))
238
+ node = tree. root
239
+ rank = 0
240
+ while node. data != key
241
+ if (node. data < key)
242
+ rank += (1 + get_subsize (node. leftChild))
243
+ node = node. rightChild
244
+ else
245
+ node = node. leftChild
246
+ end
247
+ end
248
+ rank += (1 + get_subsize (node. leftChild))
249
+ return rank
250
+ end
251
+
252
+ function Base. getindex (tree:: AVLTree{K} , ind:: Integer ) where K
253
+ @boundscheck (1 <= ind <= tree. count) || throw (BoundsError (" $ind should be in between 1 and $(tree. count) " ))
254
+ function traverse_tree (node:: AVLTreeNode_or_null , idx)
255
+ if (node != nothing )
256
+ L = get_subsize (node. leftChild)
257
+ if idx <= L
258
+ return traverse_tree (node. leftChild, idx)
259
+ elseif idx == L + 1
260
+ return node. data
261
+ else
262
+ return traverse_tree (node. rightChild, idx - L - 1 )
263
+ end
264
+ end
265
+ end
266
+ value = traverse_tree (tree. root, ind)
267
+ return value
268
+ end
0 commit comments