Skip to content

Commit d076e5b

Browse files
committed
increase coverage, add tests
1 parent 845a5fc commit d076e5b

File tree

2 files changed

+91
-12
lines changed

2 files changed

+91
-12
lines changed

src/avl_tree.jl

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
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.
15
mutable struct AVLTreeNode{K}
26
height::Int8
37
leftChild::Union{AVLTreeNode{K}, Nothing}
48
rightChild::Union{AVLTreeNode{K}, Nothing}
59
data::K
610

7-
AVLTreeNode{K}() where K = new{K}(0, nothing, nothing)
811
AVLTreeNode{K}(d::K) where K = new{K}(1, nothing, nothing, d)
912
end
1013

@@ -37,7 +40,7 @@ end
3740
fix_height(node::AVLTreeNode) = 1 + max(get_height(node.leftChild), get_height(node.rightChild))
3841

3942
"""
40-
left_rotate!(node_x::RBTreeNode)
43+
left_rotate!(node_x::AVLTreeNode)
4144
4245
Performs a left-rotation on `node_x`, updates height of the nodes, and returns the rotated node.
4346
"""
@@ -52,7 +55,7 @@ function left_rotate(z::AVLTreeNode)
5255
end
5356

5457
"""
55-
right_rotate!(node_x::RBTreeNode)
58+
right_rotate!(node_x::AVLTreeNode)
5659
5760
Performs a right-rotation on `node_x`, updates height of the nodes, and returns the rotated node.
5861
"""
@@ -67,9 +70,9 @@ function right_rotate(z::AVLTreeNode)
6770
end
6871

6972
"""
70-
minimum_node(tree::RBTree, node::RBTreeNode)
73+
minimum_node(tree::AVLTree, node::AVLTreeNode)
7174
72-
Returns the RBTreeNode with minimum value in subtree of `node`.
75+
Returns the AVLTreeNode with minimum value in subtree of `node`.
7376
"""
7477
function minimum_node(node::Union{AVLTreeNode, Nothing})
7578
while node != nothing && node.leftChild != nothing
@@ -114,6 +117,8 @@ function haskey(tree::AVLTree{K}, d::K) where K
114117
return (node.data == d)
115118
end
116119

120+
Base.in(key, tree::AVLTree) = haskey(tree, key)
121+
117122
"""
118123
insert!(tree, key)
119124
@@ -138,7 +143,7 @@ function Base.insert!(tree::AVLTree{K}, d::K) where K
138143
if balance > 1
139144
if key < node.leftChild.data
140145
return right_rotate(node)
141-
146+
else
142147
node.leftChild = left_rotate(node.leftChild)
143148
return right_rotate(node)
144149
end
@@ -198,10 +203,6 @@ function Base.delete!(tree::AVLTree{K}, d::K) where K
198203
end
199204
end
200205

201-
if node == nothing
202-
return node
203-
end
204-
205206
node.height = fix_height(node)
206207
balance = get_balance(node)
207208

@@ -234,3 +235,25 @@ function Base.delete!(tree::AVLTree{K}, d::K) where K
234235
tree.count -= 1
235236
return tree
236237
end
238+
239+
"""
240+
getindex(tree, ind)
241+
242+
Gets the key present at index `ind` of the tree. Indexing is done in increasing order of key.
243+
"""
244+
getindex(tree, ind)
245+
246+
function Base.getindex(tree::AVLTree{K}, ind) where K
247+
@boundscheck (1 <= ind <= tree.count) || throw(ArgumentError("$ind should be in between 1 and $(tree.count)"))
248+
function traverse_tree_inorder(node::Union{AVLTreeNode, Nothing})
249+
if (node != nothing)
250+
left = traverse_tree_inorder(node.leftChild)
251+
right = traverse_tree_inorder(node.rightChild)
252+
append!(push!(left, node.data), right)
253+
else
254+
return K[]
255+
end
256+
end
257+
arr = traverse_tree_inorder(tree.root)
258+
return @inbounds arr[ind]
259+
end

test/test_avl_tree.jl

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@testset "AVLTree" begin
22
@testset "inserting values" begin
33
t = AVLTree{Int}()
4-
for i in 1:100
4+
for i in 100:-1:1
55
insert!(t, i)
66
end
77

@@ -11,7 +11,7 @@
1111
@test haskey(t, i)
1212
end
1313

14-
for i = 101:200
14+
for i = 101:150
1515
@test !haskey(t, i)
1616
end
1717
end
@@ -75,4 +75,60 @@
7575
@test length(t3) == length(uniq_nums)
7676
end
7777

78+
@testset "in" begin
79+
t4 = AVLTree{Char}()
80+
push!(t4, 'a')
81+
push!(t4, 'b')
82+
@test length(t4) == 2
83+
@test in('a', t4)
84+
@test !in('c', t4)
85+
end
86+
87+
@testset "search_node" begin
88+
t5 = AVLTree()
89+
for i in 1:32
90+
push!(t5, i)
91+
end
92+
n1 = search_node(t5, 21)
93+
@test n1.data == 21
94+
n2 = search_node(t5, 35)
95+
@test n2.data == 32
96+
n3 = search_node(t5, 0)
97+
@test n3.data == 1
98+
end
99+
100+
@testset "getindex" begin
101+
t6 = AVLTree{Int}()
102+
for i in 1:10
103+
push!(t6, i)
104+
end
105+
for i in 1:10
106+
@test getindex(t6, i) == i
107+
end
108+
@test_throws ArgumentError getindex(t6, 0)
109+
@test_throws ArgumentError getindex(t6, 11)
110+
end
111+
112+
@testset "key conversion in push!" begin
113+
t7 = AVLTree{Int}()
114+
push!(t7, Int8(1))
115+
@test length(t7) == 1
116+
@test haskey(t7, 1)
117+
end
118+
119+
@testset "minimum_node" begin
120+
t8 = AVLTree()
121+
@test minimum_node(t8.root) == nothing
122+
for i in 1:32
123+
push!(t8, i)
124+
end
125+
m1 = minimum_node(t8.root)
126+
@test m1.data == 1
127+
node = t8.root
128+
while node.leftChild != nothing
129+
m = minimum_node(node.leftChild)
130+
@test m == m1
131+
node = node.leftChild
132+
end
133+
end
78134
end

0 commit comments

Comments
 (0)