Skip to content

Commit b854b90

Browse files
committed
Initial commit
1 parent a444655 commit b854b90

File tree

8 files changed

+163
-48
lines changed

8 files changed

+163
-48
lines changed

.JuliaFormatter.toml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
1-
# See https://domluna.github.io/JuliaFormatter.jl/stable/ for a list of options
1+
indent = 2
2+
margin = 90
3+
always_for_in = true
4+
always_use_return = false
5+
whitespace_typedefs = false
6+
whitespace_in_kwargs = false
7+
whitespace_ops_in_indices = true
8+
remove_extra_newlines = true
9+
trailing_comma = false
10+
normalize_line_endings = "unix"

.github/workflows/CI.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ jobs:
2323
fail-fast: false
2424
matrix:
2525
version:
26-
- '1.10'
27-
- '1.11'
28-
- 'pre'
26+
- 'lts'
27+
- '1'
2928
os:
3029
- ubuntu-latest
3130
arch:

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
*.jl.*.cov
22
*.jl.cov
33
*.jl.mem
4-
/Manifest.toml
4+
Manifest.toml
5+
.vscode
6+
*.code-workspace
7+
docs/build
8+
/.benchmarkci
9+
/benchmark/*.json

Project.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,9 @@ uuid = "289e92be-c05a-437b-9e67-5b0c799891f8"
33
authors = ["Elias Carvalho <[email protected]> and contributors"]
44
version = "0.1.0"
55

6+
[deps]
7+
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
8+
69
[compat]
10+
AbstractTrees = "0.4"
711
julia = "1.10"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# TreeDataStructures
1+
# TreeDataStructures.jl
22

33
[![Build Status](https://github.com/eliascarv/TreeDataStructures.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/eliascarv/TreeDataStructures.jl/actions/workflows/CI.yml?query=branch%3Amain)
44
[![Coverage](https://codecov.io/gh/eliascarv/TreeDataStructures.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/eliascarv/TreeDataStructures.jl)

src/TreeDataStructures.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
module TreeDataStructures
22

3-
# Write your package code here.
3+
import AbstractTrees
4+
5+
include("avl.jl")
6+
7+
export AVLTree
48

59
end

src/avl.jl

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# ---------
2+
# AVL NODE
3+
# ---------
4+
5+
mutable struct AVLNode{K,V}
6+
key::K
7+
value::V
8+
left::Union{AVLNode{K,V},Nothing}
9+
right::Union{AVLNode{K,V},Nothing}
10+
height::Int
11+
end
12+
13+
AVLNode(key, value) = AVLNode(key, value, nothing, nothing, 1)
14+
15+
Base.convert(::Type{AVLNode{K,V}}, node::AVLNode) where {K,V} =
16+
AVLNode{K,V}(node.key, node.value, node.left, node.right, node.height)
17+
18+
function AbstractTrees.children(node::AVLNode)
19+
if !isnothing(node.left) && !isnothing(node.right)
20+
(node.left, node.right)
21+
elseif !isnothing(node.left)
22+
(node.left,)
23+
elseif !isnothing(node.right)
24+
(node.right,)
25+
else
26+
()
27+
end
28+
end
29+
30+
AbstractTrees.nodevalue(node::AVLNode) = node.value
31+
32+
# ---------
33+
# AVL TREE
34+
# ---------
35+
36+
mutable struct AVLTree{K,V}
37+
root::Union{AVLNode{K,V},Nothing}
38+
end
39+
40+
AVLTree{K,V}() where {K,V} = AVLTree{K,V}(nothing)
41+
AVLTree() = AVLTree{Any,Any}()
42+
43+
function Base.getindex(tree::AVLTree{K}, key::K) where {K}
44+
node = _search(tree, key)
45+
isnothing(node) && throw(KeyError(key))
46+
node.value
47+
end
48+
49+
function Base.setindex!(tree::AVLTree, value, key)
50+
tree.root = _insert!(tree.root, key, value)
51+
tree
52+
end
53+
54+
function Base.show(io::IO, ::MIME"text/plain", tree::AVLTree)
55+
if isnothing(tree.root)
56+
print(io, "AVLTree()")
57+
else
58+
println(io, "AVLTree")
59+
str = AbstractTrees.repr_tree(tree.root, context=io)
60+
print(io, str[begin:(end - 1)]) # remove \n at end
61+
end
62+
end
63+
64+
# -----------------
65+
# HELPER FUNCTIONS
66+
# -----------------
67+
68+
function _search(tree, key)
69+
node = tree.root
70+
while !isnothing(node) && key node.key
71+
node = key < node.key ? node.left : node.right
72+
end
73+
node
74+
end
75+
76+
function _insert!(root, key, value)
77+
if isnothing(root)
78+
return AVLNode(key, value)
79+
elseif key < root.key
80+
root.left = _insert!(root.left, key, value)
81+
else
82+
root.right = _insert!(root.right, key, value)
83+
end
84+
85+
root.height = 1 + max(_height(root.left), _height(root.right))
86+
87+
bf = _balancefactor(root)
88+
89+
if bf > 1 && key < root.left.key
90+
_rightrotate!(root)
91+
elseif bf < -1 && key > root.right.key
92+
_leftrotate!(root)
93+
elseif bf > 1 && key > root.left.key
94+
_rightrotate!(root)
95+
elseif bf < -1 && key < root.right.key
96+
_leftrotate!(root)
97+
else
98+
root
99+
end
100+
end
101+
102+
_height(::Nothing) = 0
103+
_height(node::AVLNode) = node.height
104+
105+
_balancefactor(::Nothing) = 0
106+
_balancefactor(node::AVLNode) = _height(node.left) - _height(node.right)
107+
108+
_minnode(::Nothing) = nothing
109+
_minnode(node::AVLNode) = isnothing(node.left) ? node : _minnode(node.left)
110+
111+
function _leftrotate!(node)
112+
B = node.right
113+
Y = B.left
114+
115+
B.left = node
116+
node.right = Y
117+
118+
node.height = 1 + max(_height(node.left), _height(node.right))
119+
B.height = 1 + max(_height(B.left), _height(B.right))
120+
121+
B
122+
end
123+
124+
function _rightrotate!(node)
125+
A = node.left
126+
Y = A.right
127+
128+
A.right = node
129+
node.left = Y
130+
131+
node.height = 1 + max(_height(node.left), _height(node.right))
132+
A.height = 1 + max(_height(A.left), _height(A.right))
133+
134+
A
135+
end

test/Manifest.toml

Lines changed: 0 additions & 41 deletions
This file was deleted.

0 commit comments

Comments
 (0)