Skip to content

Commit e498a69

Browse files
Zzockersiriak
andauthored
chore: add AVL tree (TheAlgorithms#297)
* adding AVL tree Signed-off-by: Zzocker <[email protected]> * updating go.mod with assert pkg Signed-off-by: Zzocker <[email protected]> * removed assert pkg dep Signed-off-by: Zzocker <[email protected]> * exported delete function Signed-off-by: Zzocker <[email protected]> * ds: add AVL tree Signed-off-by: Pritam Singh <[email protected]> Co-authored-by: Andrii Siriak <[email protected]>
1 parent c3de81f commit e498a69

File tree

2 files changed

+497
-0
lines changed

2 files changed

+497
-0
lines changed

data_structures/avl/avl.go

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
// Package avl is a Adelson-Velskii and Landis tree implemnation
2+
// avl is self-balancing tree, i.e for all node in a tree, height difference
3+
// between its left and right child will not exceed 1
4+
// more information : https://en.wikipedia.org/wiki/AVL_tree
5+
package avl
6+
7+
// Node of a tree
8+
type Node struct {
9+
Key int
10+
Height int
11+
Left, Right *Node
12+
}
13+
14+
// NewTree create a new AVL tree
15+
func NewTree() *Node {
16+
return nil
17+
}
18+
19+
// Get : return node with given key
20+
func Get(root *Node, key int) *Node {
21+
if root == nil {
22+
return nil
23+
}
24+
if root.Key == key {
25+
return root
26+
} else if root.Key < key {
27+
root = root.Right
28+
} else {
29+
root = root.Left
30+
}
31+
return Get(root, key)
32+
}
33+
34+
// Insert a new item
35+
func Insert(root **Node, key int) {
36+
if *root == nil {
37+
*root = &Node{
38+
Key: key,
39+
Height: 1,
40+
}
41+
return
42+
}
43+
if (*root).Key < key {
44+
Insert(&(*root).Right, key)
45+
} else if (*root).Key > key {
46+
Insert(&(*root).Left, key)
47+
}
48+
49+
// update height
50+
(*root).Height = height(*root)
51+
52+
bFactor := balanceFactor(*root)
53+
54+
if bFactor == 2 { // L
55+
bFactor = balanceFactor((*root).Left)
56+
if bFactor == 1 { // LL
57+
llRotation(root)
58+
} else if bFactor == -1 { // LR
59+
lrRotation(root)
60+
}
61+
} else if bFactor == -2 { // R
62+
bFactor = balanceFactor((*root).Right)
63+
if bFactor == 1 { // RL
64+
rlRotation(root)
65+
} else if bFactor == -1 { // RR
66+
rrRotation(root)
67+
}
68+
}
69+
}
70+
71+
// Delete : remove given key from the tree
72+
func Delete(root **Node, key int) {
73+
if root == nil {
74+
return
75+
}
76+
if (*root).Key < key {
77+
Delete(&(*root).Right, key)
78+
} else if (*root).Key > key {
79+
Delete(&(*root).Left, key)
80+
} else {
81+
// 3 cases
82+
// 1. No Child
83+
// 2. With One Child
84+
// 3. With Two Child
85+
if (*root).Left == nil && (*root).Right == nil {
86+
*root = nil
87+
} else if (*root).Left == nil {
88+
*root = (*root).Right
89+
} else if (*root).Right == nil {
90+
*root = (*root).Left
91+
} else {
92+
minVal := min((*root).Right)
93+
(*root).Key = minVal
94+
Delete(root, minVal)
95+
}
96+
return
97+
}
98+
99+
// update height
100+
(*root).Height = height(*root)
101+
102+
bFactor := balanceFactor(*root)
103+
104+
if bFactor == 2 { // L
105+
switch balanceFactor((*root).Left) {
106+
case 1: // LL
107+
llRotation(root)
108+
case -1: // LR
109+
lrRotation(root)
110+
case 0: // LL OR LR
111+
llRotation(root)
112+
}
113+
} else if bFactor == -2 { // L
114+
switch balanceFactor((*root).Right) {
115+
case 1: // RL
116+
rlRotation(root)
117+
case -1: // RR
118+
rrRotation(root)
119+
case 0: // RL OR RR
120+
rrRotation(root)
121+
}
122+
}
123+
}
124+
125+
// rotations
126+
// 1. LL
127+
// 2. LR
128+
// 3. RR
129+
// 4. RL
130+
func llRotation(root **Node) {
131+
b := (*root).Left
132+
br := b.Right
133+
b.Right = *root
134+
(*root).Left = br
135+
(*root).Height = height(*root)
136+
b.Height = height(b)
137+
*root = b
138+
}
139+
func lrRotation(root **Node) {
140+
c := (*root).Left.Right
141+
cl := c.Left
142+
cr := c.Right
143+
144+
c.Left = (*root).Left
145+
c.Right = (*root)
146+
c.Left.Right = cl
147+
148+
(*root).Left = cr
149+
150+
(*root).Height = height(*root)
151+
c.Left.Height = height(c.Left)
152+
c.Height = height(c)
153+
154+
*root = c
155+
156+
}
157+
func rrRotation(root **Node) {
158+
b := (*root).Right
159+
bl := b.Left
160+
b.Left = *root
161+
162+
(*root).Right = bl
163+
(*root).Height = height(*root)
164+
b.Height = height(b)
165+
*root = b
166+
167+
}
168+
func rlRotation(root **Node) {
169+
c := (*root).Right.Left
170+
cl := c.Left
171+
cr := c.Right
172+
173+
c.Right = (*root).Right
174+
c.Right.Left = cr
175+
c.Left = *root
176+
(*root).Right = cl
177+
178+
(*root).Height = height(*root)
179+
c.Right.Height = height(c.Right)
180+
c.Height = height(c)
181+
*root = c
182+
}
183+
184+
// balanceFactor : -ve balance factor means subtree root is heavy toward left
185+
// and +ve balance factor means subtree root is heavy toward right side
186+
func balanceFactor(root *Node) int {
187+
var leftHeight, rightHeight int
188+
if root.Left != nil {
189+
leftHeight = root.Left.Height
190+
}
191+
if root.Right != nil {
192+
rightHeight = root.Right.Height
193+
}
194+
return leftHeight - rightHeight
195+
}
196+
197+
func height(root *Node) int {
198+
if root == nil {
199+
return 0
200+
}
201+
var leftHeight, rightHeight int
202+
if root.Left != nil {
203+
leftHeight = root.Left.Height
204+
}
205+
if root.Right != nil {
206+
rightHeight = root.Right.Height
207+
}
208+
max := leftHeight
209+
if rightHeight > leftHeight {
210+
max = rightHeight
211+
}
212+
return 1 + max
213+
}
214+
215+
func min(root *Node) int {
216+
if root.Left == nil {
217+
return root.Key
218+
}
219+
return min(root.Left)
220+
}

0 commit comments

Comments
 (0)