@@ -78,7 +78,8 @@ keywords: "AA tree, balanced BST, self-balancing tree, skew, split, C++, Python,
7878- # Implementation
7979 collapsed:: true
8080 - > [!note] AA Tree Implementation
81- > Below are complete, production-ready implementations in Python and C++ for AA Trees, including search, skew, split, insert, and delete rebalancing operations.
81+ > Below are complete implementations for AA Trees, including search, skew, split, and insert operations.
82+ > Languages: [[Python]] · [[Cpp]] · [[Java Script]] · [[Java]] · [[C]]
8283 -
8384 - :::code-tabs
8485
@@ -215,7 +216,7 @@ keywords: "AA tree, balanced BST, self-balancing tree, skew, split, C++, Python,
215216 print("Search 15 after removal:", tree.search(15)) # Output: False
216217 ```
217218
218- ```cpp
219+ ```c++
219220 #include <iostream>
220221 #include <vector>
221222 #include <algorithm>
@@ -365,10 +366,216 @@ keywords: "AA tree, balanced BST, self-balancing tree, skew, split, C++, Python,
365366 }
366367 ```
367368
369+ ```javascript
370+ class AANode {
371+ constructor(key) {
372+ this.key = key;
373+ this.level = 1;
374+ this.left = null;
375+ this.right = null;
376+ }
377+ }
378+
379+ class AATree {
380+ constructor() {
381+ this.root = null;
382+ }
383+
384+ skew(node) {
385+ if (!node || !node.left) return node;
386+ if (node.left.level === node.level) {
387+ let leftChild = node.left;
388+ node.left = leftChild.right;
389+ leftChild.right = node;
390+ return leftChild;
391+ }
392+ return node;
393+ }
394+
395+ split(node) {
396+ if (!node || !node.right || !node.right.right) return node;
397+ if (node.right.right.level === node.level) {
398+ let rightChild = node.right;
399+ node.right = rightChild.left;
400+ rightChild.left = node;
401+ rightChild.level++;
402+ return rightChild;
403+ }
404+ return node;
405+ }
406+
407+ insert(key) {
408+ this.root = this._insert(this.root, key);
409+ }
410+
411+ _insert(node, key) {
412+ if (!node) return new AANode(key);
413+ if (key < node.key) {
414+ node.left = this._insert(node.left, key);
415+ } else if (key > node.key) {
416+ node.right = this._insert(node.right, key);
417+ } else {
418+ return node;
419+ }
420+ node = this.skew(node);
421+ node = this.split(node);
422+ return node;
423+ }
424+
425+ search(key) {
426+ let curr = this.root;
427+ while (curr) {
428+ if (key === curr.key) return true;
429+ else if (key < curr.key) curr = curr.left;
430+ else curr = curr.right;
431+ }
432+ return false;
433+ }
434+ }
435+ ```
436+
437+ ```java
438+ class AANode {
439+ int key, level;
440+ AANode left, right;
441+ public AANode(int key) {
442+ this.key = key;
443+ this.level = 1;
444+ }
445+ }
446+
447+ public class AATree {
448+ private AANode root;
449+
450+ private AANode skew(AANode node) {
451+ if (node == null || node.left == null) return node;
452+ if (node.left.level == node.level) {
453+ AANode leftChild = node.left;
454+ node.left = leftChild.right;
455+ leftChild.right = node;
456+ return leftChild;
457+ }
458+ return node;
459+ }
460+
461+ private AANode split(AANode node) {
462+ if (node == null || node.right == null || node.right.right == null) return node;
463+ if (node.right.right.level == node.level) {
464+ AANode rightChild = node.right;
465+ node.right = rightChild.left;
466+ rightChild.left = node;
467+ rightChild.level++;
468+ return rightChild;
469+ }
470+ return node;
471+ }
472+
473+ public void insert(int key) {
474+ root = insertRec(root, key);
475+ }
476+
477+ private AANode insertRec(AANode node, int key) {
478+ if (node == null) return new AANode(key);
479+ if (key < node.key) node.left = insertRec(node.left, key);
480+ else if (key > node.key) node.right = insertRec(node.right, key);
481+ else return node;
482+
483+ node = skew(node);
484+ node = split(node);
485+ return node;
486+ }
487+
488+ public boolean search(int key) {
489+ AANode curr = root;
490+ while (curr != null) {
491+ if (key == curr.key) return true;
492+ else if (key < curr.key) curr = curr.left;
493+ else curr = curr.right;
494+ }
495+ return false;
496+ }
497+ }
498+ ```
499+
500+ ```c
501+ #include <stdio.h>
502+ #include <stdlib.h>
503+
504+ typedef struct AANode {
505+ int key;
506+ int level;
507+ struct AANode *left, *right;
508+ } AANode;
509+
510+ AANode* createNode(int key) {
511+ AANode* node = (AANode*)malloc(sizeof(AANode));
512+ node->key = key;
513+ node->level = 1;
514+ node->left = node->right = NULL;
515+ return node;
516+ }
517+
518+ AANode* skew(AANode* node) {
519+ if (node == NULL || node->left == NULL) return node;
520+ if (node->left->level == node->level) {
521+ AANode* leftChild = node->left;
522+ node->left = leftChild->right;
523+ leftChild->right = node;
524+ return leftChild;
525+ }
526+ return node;
527+ }
528+
529+ AANode* split(AANode* node) {
530+ if (node == NULL || node->right == NULL || node->right->right == NULL) return node;
531+ if (node->right->right->level == node->level) {
532+ AANode* rightChild = node->right;
533+ node->right = rightChild->left;
534+ rightChild->left = node;
535+ rightChild->level++;
536+ return rightChild;
537+ }
538+ return node;
539+ }
540+
541+ AANode* insert(AANode* node, int key) {
542+ if (node == NULL) return createNode(key);
543+ if (key < node->key) node->left = insert(node->left, key);
544+ else if (key > node->key) node->right = insert(node->right, key);
545+ else return node;
546+
547+ node = skew(node);
548+ node = split(node);
549+ return node;
550+ }
551+
552+ int search(AANode* root, int key) {
553+ AANode* curr = root;
554+ while (curr != NULL) {
555+ if (key == curr->key) return 1;
556+ else if (key < curr->key) curr = curr->left;
557+ else curr = curr->right;
558+ }
559+ return 0;
560+ }
561+ ```
562+
368563 :::
369564-
370565- # When to Use
371566 collapsed:: true
567+ - ```mermaid
568+ flowchart TD
569+ Q{"Need a self-balancing\nbinary search tree?"}
570+ Q -- No --> S1{"Static data?"}
571+ S1 -- Yes --> R1["✅ Use standard BST\nor sorted array"]
572+ Q -- Yes --> S2{"Are you implementing\nit from scratch?"}
573+ S2 -- No --> R2["✅ Use standard library\nRed-Black Tree (std::map, TreeMap)"]
574+ S2 -- Yes --> S3{"Need simpler code\nthan Red-Black Tree?"}
575+ S3 -- Yes --> R3["✅ Use AA Tree"]
576+ S3 -- No --> R4["✅ Use AVL or Red-Black"]
577+ ```
578+ -
372579 - ## ✅ Use AA Tree When:
373580 - You want to implement a self-balancing BST from scratch and want to avoid the complex edge-cases of Red-Black Trees.
374581 - Standard libraries aren't available, and coding simplicity is paramount.
@@ -388,4 +595,9 @@ keywords: "AA tree, balanced BST, self-balancing tree, skew, split, C++, Python,
388595 - AA Trees enforce balance via integer **levels** instead of node colors.
389596 - They eliminate left-leaning horizontal links by only allowing red links to lean right.
390597 - Two operations, **skew** (right rotate) and **split** (left rotate and level up), handle all insertion balance needs.
391- - The worst-case height is $O(\log n)$, guaranteeing lookup, insert, and delete in $O(\log n)$ time.
598+ - The worst-case height is $O(\log n)$, guaranteeing lookup, insert, and delete in $O(\log n)$ time.
599+ -
600+ - # More Learn
601+ - ## GitHub & Webs
602+ - [TheAlgorithms – Binary Tree](https://github.com/TheAlgorithms/Python/tree/master/data_structures/binary_tree)
603+ - [Wikipedia - AA tree](https://en.wikipedia.org/wiki/AA_tree)
0 commit comments