Skip to content

Commit 8a17fd0

Browse files
author
VR-Rathod
committed
Inchance notes
1 parent 08aef6f commit 8a17fd0

File tree

6 files changed

+1143
-252
lines changed

6 files changed

+1143
-252
lines changed

pages/AA Tree.md

Lines changed: 252 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,260 @@
11
---
2-
seoTitle: AA Tree Explained – Balanced BST Implementation Guide
3-
description: "AA tree is a balanced binary search tree variant of red-black trees. Learn insertion, deletion, skew, split operations, and time complexity analysis."
4-
keywords: "AA tree, balanced BST, self-balancing tree, binary search tree, skew operation, split operation, time complexity, space complexity, tree rotation, data structures"
2+
seoTitle: AA Tree Explained – Self-Balancing BST with C++ Implementation
3+
description: "AA Tree is a simplified variant of Red-Black Tree. Learn skew, split, insertion, deletion, and search with C++ code examples and complexity analysis."
4+
keywords: "AA tree, balanced BST, self-balancing tree, skew, split, C++, data structures, algorithms, binary search tree, tree rotation"
55
---
66

7-
# Explanation
8-
- The **AA Tree** is a self-balancing binary search tree (BST). It’s a variation of the Red-Black Tree but with a simpler set of rules. The primary difference lies in how the tree is balanced, and it ensures that operations like insertion, deletion, and searching remain efficient.
7+
- # History
8+
- **Invented by**: Arne Andersson in 1993.
9+
- **Why**: Simplify the Red-Black Tree by restricting left red links only — fewer cases to handle during rebalancing.
10+
- **Named after**: Arne Andersson → "AA" Tree.
911
-
10-
- # Steps:
11-
- The **balance condition** is enforced with a single balance factor for each node (the "level"), which simplifies the balancing process.
12+
- # Introduction
13+
- An **AA Tree** is a self-balancing Binary Search Tree (BST) — a simplified variant of the Red-Black Tree.
14+
- Instead of colors, it uses a **level** (integer) per node to enforce balance.
15+
- Only **right children** can have the same level as their parent (no left horizontal links allowed).
16+
- Two operations maintain balance: **Skew** (fix left horizontal link) and **Split** (fix double right horizontal link).
1217
-
13-
- **Level Rule**: The left child of a node must have the same level or one more level than its parent.
18+
- ## Advantages
19+
- Simpler implementation than Red-Black Trees (fewer rotation cases).
20+
- Guaranteed O(log n) for insert, delete, search.
21+
- Easier to reason about correctness.
1422
-
15-
- **Rotation Rule**: The tree uses rotations (like right or left) to ensure the balance after insertion or deletion.
23+
- ## Disadvantages
24+
- Slightly slower than Red-Black Trees in practice due to extra passes.
25+
- Less commonly used, so fewer library implementations available.
1626
-
17-
- # Time Complexity
18-
- **Insertion**: O(log n)
19-
- **Deletion**: O(log n)
20-
- **Search**: O(log n)
27+
- # Core Concepts
28+
- ## Level Rule
29+
collapsed:: true
30+
- Every node has an integer **level**.
31+
- Leaf nodes have level 1.
32+
- Left child level must be exactly **one less** than parent level.
33+
- Right child level must be **equal or one less** than parent level.
34+
- Right grandchild level must be **strictly less** than parent level.
35+
-
36+
- ## Skew (Fix Left Horizontal Link)
37+
- A **right rotation** to remove a left horizontal link (left child same level as parent).
38+
- ```
39+
| → |
40+
T(lvl) L(lvl)
41+
/ \ / \
42+
L(lvl) R LL T(lvl)
43+
/ \ / \
44+
LL LR LR R
45+
```
46+
- ```cpp
47+
Node* skew(Node* T) {
48+
if (T && T->left && T->left->level == T->level) {
49+
Node* L = T->left;
50+
T->left = L->right;
51+
L->right = T;
52+
return L;
53+
}
54+
return T;
55+
}
56+
```
57+
-
58+
- ## Split (Fix Double Right Horizontal Link)
59+
collapsed:: true
60+
- A **left rotation + level increment** to remove two consecutive right horizontal links.
61+
- ```
62+
| → |
63+
T(lvl) R(lvl+1)
64+
/ \ / \
65+
A R(lvl) T(lvl) RR(lvl)
66+
/ \ / \
67+
RL RR(lvl) A RL
68+
```
69+
- ```cpp
70+
Node* split(Node* T) {
71+
if (T && T->right && T->right->right &&
72+
T->right->right->level == T->level) {
73+
Node* R = T->right;
74+
T->right = R->left;
75+
R->left = T;
76+
R->level++;
77+
return R;
78+
}
79+
return T;
80+
}
81+
```
82+
-
83+
- # C++ Implementation
84+
- ## Node Structure
85+
collapsed:: true
86+
- ```cpp
87+
#include <iostream>
88+
89+
struct Node {
90+
int key;
91+
int level;
92+
Node* left;
93+
Node* right;
94+
95+
Node(int k) : key(k), level(1), left(nullptr), right(nullptr) {}
96+
};
97+
```
98+
-
99+
- ## Skew & Split
100+
collapsed:: true
101+
- ```cpp
102+
Node* skew(Node* T) {
103+
if (T && T->left && T->left->level == T->level) {
104+
Node* L = T->left;
105+
T->left = L->right;
106+
L->right = T;
107+
return L;
108+
}
109+
return T;
110+
}
111+
112+
Node* split(Node* T) {
113+
if (T && T->right && T->right->right &&
114+
T->right->right->level == T->level) {
115+
Node* R = T->right;
116+
T->right = R->left;
117+
R->left = T;
118+
R->level++;
119+
return R;
120+
}
121+
return T;
122+
}
123+
```
124+
-
125+
- ## Insert
126+
collapsed:: true
127+
- ```cpp
128+
Node* insert(Node* T, int key) {
129+
if (!T) return new Node(key);
130+
131+
if (key < T->key)
132+
T->left = insert(T->left, key);
133+
else if (key > T->key)
134+
T->right = insert(T->right, key);
135+
else
136+
return T; // duplicate — ignore
137+
138+
T = skew(T);
139+
T = split(T);
140+
return T;
141+
}
142+
```
143+
-
144+
- ## Search
145+
collapsed:: true
146+
- ```cpp
147+
Node* search(Node* T, int key) {
148+
if (!T || T->key == key) return T;
149+
if (key < T->key) return search(T->left, key);
150+
return search(T->right, key);
151+
}
152+
```
153+
-
154+
- ## Delete (with rebalance helpers)
155+
collapsed:: true
156+
- ```cpp
157+
// Find minimum node in subtree
158+
Node* findMin(Node* T) {
159+
while (T->left) T = T->left;
160+
return T;
161+
}
162+
163+
// Decrease level if needed after deletion
164+
Node* decreaseLevel(Node* T) {
165+
int shouldBe = std::min(
166+
T->left ? T->left->level : 0,
167+
T->right ? T->right->level : 0
168+
) + 1;
169+
170+
if (shouldBe < T->level) {
171+
T->level = shouldBe;
172+
if (T->right && shouldBe < T->right->level)
173+
T->right->level = shouldBe;
174+
}
175+
return T;
176+
}
177+
178+
Node* remove(Node* T, int key) {
179+
if (!T) return nullptr;
180+
181+
if (key < T->key)
182+
T->left = remove(T->left, key);
183+
else if (key > T->key)
184+
T->right = remove(T->right, key);
185+
else {
186+
if (!T->left && !T->right) { delete T; return nullptr; }
187+
if (!T->left) {
188+
Node* succ = findMin(T->right);
189+
T->key = succ->key;
190+
T->right = remove(T->right, succ->key);
191+
} else {
192+
// find predecessor
193+
Node* pred = T->left;
194+
while (pred->right) pred = pred->right;
195+
T->key = pred->key;
196+
T->left = remove(T->left, pred->key);
197+
}
198+
}
199+
200+
T = decreaseLevel(T);
201+
T = skew(T);
202+
if (T->right) T->right = skew(T->right);
203+
if (T->right && T->right->right) T->right->right = skew(T->right->right);
204+
T = split(T);
205+
if (T->right) T->right = split(T->right);
206+
return T;
207+
}
208+
```
209+
-
210+
- ## Full Usage Example
211+
collapsed:: true
212+
- ```cpp
213+
int main() {
214+
Node* root = nullptr;
215+
216+
// Insert
217+
for (int k : {5, 3, 7, 1, 4, 6, 8})
218+
root = insert(root, k);
219+
220+
// Search
221+
Node* found = search(root, 4);
222+
std::cout << (found ? "Found: " + std::to_string(found->key) : "Not found") << "\n";
223+
// Found: 4
224+
225+
// Delete
226+
root = remove(root, 3);
227+
std::cout << (search(root, 3) ? "Still there" : "Deleted") << "\n";
228+
// Deleted
229+
230+
return 0;
231+
}
232+
```
233+
-
234+
- # Time & Space Complexity
235+
collapsed:: true
236+
- ```
237+
Operation Time (avg) Time (worst) Space
238+
Search O(log n) O(log n) O(log n) stack
239+
Insert O(log n) O(log n) O(log n) stack
240+
Delete O(log n) O(log n) O(log n) stack
241+
Space (tree) — — O(n)
242+
```
243+
- Height is always **O(log n)** — guaranteed by level invariants.
244+
-
245+
- # AA Tree vs Red-Black Tree
246+
collapsed:: true
247+
- ```
248+
Property AA Tree Red-Black Tree
249+
Balance via Levels Colors (Red/Black)
250+
Left red links Not allowed Allowed
251+
Rotation cases 2 (skew, split) Up to 6
252+
Implementation Simpler More complex
253+
Performance Slightly slower Slightly faster
254+
```
21255
-
22-
- ```python
23-
class AATreeNode:
24-
def __init__(self, key):
25-
self.key = key
26-
self.level = 1
27-
self.left = None
28-
self.right = None
29-
30-
class AATree:
31-
def __init__(self):
32-
self.root = None
33-
34-
def skew(self, node):
35-
if node and node.left and node.left.level == node.level:
36-
node = self.rotate_right(node)
37-
return node
38-
39-
def split(self, node):
40-
if node and node.right and node.right.right and node.right.right.level == node.level:
41-
node = self.rotate_left(node)
42-
node.level += 1
43-
return node
44-
45-
def rotate_right(self, node):
46-
temp = node.left
47-
node.left = temp.right
48-
temp.right = node
49-
return temp
50-
51-
def rotate_left(self, node):
52-
temp = node.right
53-
node.right = temp.left
54-
temp.left = node
55-
return temp
56-
57-
def insert(self, node, key):
58-
if node is None:
59-
return AATreeNode(key)
60-
61-
if key < node.key:
62-
node.left = self.insert(node.left, key)
63-
elif key > node.key:
64-
node.right = self.insert(node.right, key)
65-
else:
66-
return node
67-
68-
node = self.skew(node)
69-
node = self.split(node)
70-
return node
71-
72-
def search(self, node, key):
73-
if node is None or node.key == key:
74-
return node
75-
elif key < node.key:
76-
return self.search(node.left, key)
77-
else:
78-
return self.search(node.right, key)
79-
80-
def add(self, key):
81-
self.root = self.insert(self.root, key)
82-
83-
# Example usage
84-
aatree = AATree()
85-
aatree.add(10)
86-
aatree.add(20)
87-
aatree.add(5)
88-
89-
result = aatree.search(aatree.root, 10)
90-
if result:
91-
print(f"Found key {result.key}")
92-
else:
93-
print("Key not found")
94-
```
256+
- # Key Takeaways
257+
- AA Tree = Red-Black Tree with **only right horizontal links** allowed.
258+
- Two operations: **skew** (right rotation) and **split** (left rotation + level up).
259+
- All operations run in **O(log n)** guaranteed.
260+
- Great choice when you want a balanced BST with simpler code than Red-Black.

0 commit comments

Comments
 (0)