diff --git a/docs/data-structure-and-algorithms/data-structures/tree/binary-tree.md b/docs/data-structure-and-algorithms/data-structures/tree/binary-tree.md index 4604c9fe..1d36684f 100644 --- a/docs/data-structure-and-algorithms/data-structures/tree/binary-tree.md +++ b/docs/data-structure-and-algorithms/data-structures/tree/binary-tree.md @@ -4,6 +4,12 @@ sidebar_position: 2 # Binary Tree +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + A **Binary Tree** is a hierarchical data structure where each node has at most **two children**, referred to as the **left child** and **right child**. ## Key Properties diff --git a/docs/data-structure-and-algorithms/data-structures/tree/common-algorithms.md b/docs/data-structure-and-algorithms/data-structures/tree/common-algorithms.md index f999e782..1ec02ad5 100644 --- a/docs/data-structure-and-algorithms/data-structures/tree/common-algorithms.md +++ b/docs/data-structure-and-algorithms/data-structures/tree/common-algorithms.md @@ -4,7 +4,11 @@ sidebar_position: 9 # Common Tree Algorithms - +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: ## Generating Binary Tree from In-order and Post-order Traversals diff --git a/docs/data-structure-and-algorithms/data-structures/tree/full-vs-complete-binary-tree.md b/docs/data-structure-and-algorithms/data-structures/tree/full-vs-complete-binary-tree.md index 42c5e2b4..f09a6ea2 100644 --- a/docs/data-structure-and-algorithms/data-structures/tree/full-vs-complete-binary-tree.md +++ b/docs/data-structure-and-algorithms/data-structures/tree/full-vs-complete-binary-tree.md @@ -4,7 +4,11 @@ sidebar_position: 6 # Full vs Complete Binary Tree - +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: ## Full Binary Tree diff --git a/docs/data-structure-and-algorithms/data-structures/tree/introduction.md b/docs/data-structure-and-algorithms/data-structures/tree/introduction.md index dd1630cd..e587800e 100644 --- a/docs/data-structure-and-algorithms/data-structures/tree/introduction.md +++ b/docs/data-structure-and-algorithms/data-structures/tree/introduction.md @@ -4,6 +4,12 @@ sidebar_position: 1 # Introduction +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + A **tree** is a widely used abstract data structure that simulates a hierarchical tree structure, with a root value and subtrees of children, represented as a set of linked nodes. Trees are fundamental in computer science and are used in various applications such as databases, file systems, compilers, and more. ## Tree Terminology diff --git a/docs/data-structure-and-algorithms/data-structures/tree/n-ary-tree.md b/docs/data-structure-and-algorithms/data-structures/tree/n-ary-tree.md index 63ba000d..15afbcc4 100644 --- a/docs/data-structure-and-algorithms/data-structures/tree/n-ary-tree.md +++ b/docs/data-structure-and-algorithms/data-structures/tree/n-ary-tree.md @@ -4,6 +4,12 @@ sidebar_position: 4 # N-ary Tree +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + An **n-ary tree** is a rooted tree in which each node can have at most `n` children. This generalizes the binary tree concept to any number of children. - If `n = 2`, it’s a binary tree. diff --git a/docs/data-structure-and-algorithms/data-structures/tree/search-tree/_category_.json b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/_category_.json new file mode 100644 index 00000000..9e046127 --- /dev/null +++ b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Search Tree", + "position": 10 +} \ No newline at end of file diff --git a/docs/data-structure-and-algorithms/data-structures/bst/_category_.json b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/bst/_category_.json similarity index 66% rename from docs/data-structure-and-algorithms/data-structures/bst/_category_.json rename to docs/data-structure-and-algorithms/data-structures/tree/search-tree/bst/_category_.json index f90454b9..f8852580 100644 --- a/docs/data-structure-and-algorithms/data-structures/bst/_category_.json +++ b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/bst/_category_.json @@ -1,4 +1,4 @@ { "label": "Binary Search Tree", - "position": 8 -} + "position": 2 +} \ No newline at end of file diff --git a/docs/data-structure-and-algorithms/data-structures/bst/introduction.md b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/bst/introduction.md similarity index 96% rename from docs/data-structure-and-algorithms/data-structures/bst/introduction.md rename to docs/data-structure-and-algorithms/data-structures/tree/search-tree/bst/introduction.md index b3100bba..c87197cb 100644 --- a/docs/data-structure-and-algorithms/data-structures/bst/introduction.md +++ b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/bst/introduction.md @@ -4,6 +4,12 @@ sidebar_position: 1 # Introduction +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + A **Binary Search Tree (BST)** is a type of binary tree where each node satisfies the **BST property**: - **Left Subtree**: All values in the left subtree are **less than** the node’s value. diff --git a/docs/data-structure-and-algorithms/data-structures/bst/key-operations.md b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/bst/key-operations.md similarity index 99% rename from docs/data-structure-and-algorithms/data-structures/bst/key-operations.md rename to docs/data-structure-and-algorithms/data-structures/tree/search-tree/bst/key-operations.md index 5faa5f09..e93dff25 100644 --- a/docs/data-structure-and-algorithms/data-structures/bst/key-operations.md +++ b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/bst/key-operations.md @@ -4,6 +4,12 @@ sidebar_position: 2 # Common BST Algorithms +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + A **Binary Search Tree** supports a variety of operations to insert, find, delete, construct the tree from traversal data, validate properties, and perform traversals while maintaining the BST property. ## Search in BST diff --git a/docs/data-structure-and-algorithms/data-structures/tree/search-tree/introduction.md b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/introduction.md new file mode 100644 index 00000000..06a016d7 --- /dev/null +++ b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/introduction.md @@ -0,0 +1,41 @@ +--- +sidebar_position: 1 +--- + +# Introduction + +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + +A search tree is a tree data structure that organizes data in a way that allows efficient searching, insertion, and deletion of elements. + +Unlike a general tree, a search tree follows specific rules that determine where elements are stored. These rules enable algorithms to eliminate large portions of the tree during a search, making operations significantly faster than scanning every node. + +For example, in a well-structured search tree, finding an element may require visiting only a small fraction of the nodes, resulting in a time complexity of **O(log n)** instead of **O(n)**. + +Search trees are widely used in databases, file systems, compilers, search engines, caches, and many other software systems. + +## Why Do We Need Search Trees? + +Consider searching for a value in an unsorted collection of data: + +```text +10, 50, 20, 70, 30, 40 +``` + +In the worst case, every element must be examined. + +```text +Search Complexity = O(n) +``` + +Search trees organize data according to defined rules, allowing searches to discard large portions of the structure at each step. + +```text +Search Complexity = O(log n) (for balanced search trees) +``` + +As the amount of data grows, this difference becomes significant. diff --git a/docs/data-structure-and-algorithms/data-structures/tree/search-tree/prefix-search-tree/_category_.json b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/prefix-search-tree/_category_.json new file mode 100644 index 00000000..c62521e9 --- /dev/null +++ b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/prefix-search-tree/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Prefix Search Tree", + "position": 4 +} \ No newline at end of file diff --git a/docs/data-structure-and-algorithms/data-structures/tree/search-tree/prefix-search-tree/introduction.md b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/prefix-search-tree/introduction.md new file mode 100644 index 00000000..c9e6df33 --- /dev/null +++ b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/prefix-search-tree/introduction.md @@ -0,0 +1,34 @@ +--- +sidebar_position: 1 +--- + +# Introduction + +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + +A Prefix Search Tree is a tree data structure designed for storing and searching strings based on their prefixes. + +Unlike Binary Search Trees, which organize data using value comparisons, Prefix Search Trees organize data character by character. This allows strings that share a common prefix to share the same path in the tree. + +For example, the words: + +```text +cat +car +can +``` + +share the prefix `"ca"` and therefore share part of the same path in the tree. + +Prefix Search Trees are commonly used in: + +- Autocomplete systems +- Spell checkers +- Dictionaries +- Prefix-based searches + +The most common Prefix Search Tree is the **Trie**. diff --git a/docs/data-structure-and-algorithms/data-structures/tree/search-tree/prefix-search-tree/trie.md b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/prefix-search-tree/trie.md new file mode 100644 index 00000000..d7f18069 --- /dev/null +++ b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/prefix-search-tree/trie.md @@ -0,0 +1,429 @@ +--- +sidebar_position: 2 +--- + +# Trie + +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + +A Trie (pronounced "try"), also known as a **Prefix Tree**, is a tree-based data structure used to efficiently store and search strings. + +Unlike Binary Search Trees, which organize data using value comparisons, a Trie organizes data character by character. Strings that share a common prefix share the same path in the tree. + +Tries are commonly used for: + +- Autocomplete systems +- Spell checkers +- Dictionaries +- Search suggestions +- IP routing +- Word games + +## Why Do We Need a Trie? + +Consider storing the following words: + +```text +cat +car +can +``` + +A hash table can tell us whether a word exists, but it cannot efficiently answer questions like: + +```text +Words starting with "ca" ? +``` + +A Trie is specifically designed for prefix-based operations. + +## Trie Structure + +Each node represents a character. + +The path from the root to a node forms a prefix. + +A special marker is used to indicate the end of a complete word. + +### Example + +Words: + +```text +cat +car +can +``` + +
+ +```mermaid +graph TD + +root((Root)) + +root --> c[c] +c --> a[a] + +a --> t[t] +a --> r[r] +a --> n[n] + +t --> te((End)) +r --> re((End)) +n --> ne((End)) +``` + +
+ +Notice how all three words share the prefix: + +```text +ca +``` + +## Trie Node Structure + +A typical Trie node contains: + +```text +children +isEndOfWord +``` + +### Conceptual Representation + +```text +TrieNode +├── children +└── isEndOfWord +``` + +## Example Trie + +Words: + +```text +cat +car +care +dog +``` + +
+ +```mermaid +graph TD + + root((Root)) + + root --> c[c] + root --> d[d] + + c --> a[a] + a --> t[t] + a --> r[r] + + r --> e[e] + + d --> o[o] + o --> g[g] + + t --> tEnd((End)) + r --> rEnd((End)) + e --> eEnd((End)) + g --> gEnd((End)) +``` + +
+ +## Common Trie Operations + +### Insert + +To insert a word: + +1. Start at the root. +2. Process each character. +3. Create nodes if they do not exist. +4. Mark the last character as a complete word. + +#### Insert "cat" + +
+ +```mermaid +graph TD + + root((Root)) + + root --> c[c] + + c --> a[a] + a --> t[t] + t --> wordEnd((End)) +``` + +
+ +#### Time Complexity + +```text +O(m) +``` + +where: + +```text +m = length of word +``` + +### Search + +To search for a word: + +1. Start from the root. +2. Follow the path for each character. +3. If any character is missing, the word does not exist. +4. Verify that the final node is marked as a complete word. + +#### Example + +Searching: + +```text +cat +``` + +Path: + +```text +Root → c → a → t +``` + +Result: + +```text +Found +``` + +#### Time Complexity + +```text +O(m) +``` + +### Prefix Search + +One of the biggest advantages of a Trie. + +Question: + +```text +Does any word start with "ca"? +``` + +Traversal: + +```text +Root → c → a +``` + +If the path exists: + +```text +Prefix Exists +``` + +No need to traverse the entire tree. + +#### Time Complexity + +```text +O(m) +``` + +### Deletion + +Deletion is more complicated than insertion and search. + +Consider: + +```text +car +care +``` + +Deleting: + +```text +care +``` + +should not remove: + +```text +car +``` + +#### Before Deletion + +
+ +```mermaid +graph TD + +root((Root)) +root --> c[c] +c --> a[a] +a --> r[r] +r --> e[e] + +r --> rEnd((End)) +e --> eEnd((End)) +``` + +
+ +#### After Deletion + +
+ +```mermaid +graph TD + +root((Root)) +root --> c[c] +c --> a[a] +a --> r[r] + +r --> rEnd((End)) +``` + +
+ +The node `e` can be removed because no other word uses it. + +#### Time Complexity + +```text +O(m) +``` + +## Prefix Sharing + +The major strength of a Trie is prefix sharing. + +Words: + +```text +apple +app +application +apply +``` + +
+ +```mermaid +graph TD + +root((Root)) + +root --> a[a] +a --> p1[p] +p1 --> p2[p] + +p2 --> l[l] + +l --> e[e] +l --> i[i] +l --> y[y] + +i --> c[c] + +p2 --> appEnd((app)) +e --> appleEnd((apple)) +``` + +
+ +All words reuse the same prefix: + +```text +app +``` + +## Complexity Analysis + +Let: + +```text +m = length of key +``` + +| Operation | Complexity | +| ------------- | ---------- | +| Insert | O(m) | +| Search | O(m) | +| Prefix Search | O(m) | +| Delete | O(m) | + +## Trie vs Hash Table + +| Feature | Trie | Hash Table | +| ----------------- | --------- | ----------- | +| Search Word | O(m) | O(m) | +| Prefix Search | Efficient | Inefficient | +| Autocomplete | Excellent | Poor | +| Ordered Traversal | Yes | No | +| Memory Usage | Higher | Lower | + +## Advantages + +- Fast prefix search +- Efficient autocomplete +- Shared prefixes reduce duplication +- Predictable performance +- Naturally supports lexicographical traversal + +## Disadvantages + +- High memory usage +- Large alphabet increases storage requirements +- More complex than hash tables + +## Variants of Trie + +### Compressed Trie (Radix Tree) + +Chains of single-child nodes are compressed. + +```text +c → a → t +``` + +becomes: + +```text +cat +``` + +Reducing memory usage. + +### Ternary Search Trie + +Combines ideas from: + +- Trie +- Binary Search Tree + +### Suffix Trie + +Stores all suffixes of a string. + +Used in advanced string matching algorithms. diff --git a/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/_category_.json b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/_category_.json new file mode 100644 index 00000000..6ba28bd2 --- /dev/null +++ b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Self-Balancing BST", + "position": 3 +} \ No newline at end of file diff --git a/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/avl.md b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/avl.md new file mode 100644 index 00000000..d58d8b72 --- /dev/null +++ b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/avl.md @@ -0,0 +1,744 @@ +--- +sidebar_position: 2 +--- + +# AVL Tree + +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + +An **AVL Tree** (Adelson-Velsky and Landis Tree) is a **self-balancing Binary Search Tree (BST)** in which the height difference between the left and right subtrees of every node is at most **1**. + +AVL Trees automatically perform **rotations** after insertions and deletions to maintain balance, ensuring that search, insertion, and deletion operations remain efficient. + +## Why Do We Need AVL Trees? + +A regular BST can become skewed depending on the insertion order. + +### Example + +Insert: + +```text +10, 20, 30, 40, 50 +``` + +Resulting BST: + +
+ +```mermaid +graph TD + 10((10)) --> 0((_)) + 10 --> 20((20)) + + 20 --> 2((_)) + 20 --> 30((30)) + + 30 --> 3((_)) + 30 --> 40((40)) + + 40 --> 4((_)) + 40 --> 50((50)) +``` + +
+ +The tree behaves like a linked list. + +```text +Height = O(n) +Search = O(n) +Insert = O(n) +Delete = O(n) +``` + +AVL Trees prevent this degeneration by maintaining balance. + +Balanced AVL Tree: + +
+ +```mermaid +graph TD + A((30)) --> B((20)) + A --> C((40)) + B --> D((10)) + C --> E((50)) +``` + +
+ +```text +Height ≈ O(log n) +``` + +## AVL Tree Properties + +Every AVL Tree must satisfy: + +### Binary Search Tree Property + +For every node: + +```text +Left Subtree < Node < Right Subtree +``` + +Example: + +
+ +```mermaid +graph TD + A((50)) --> B((30)) + A --> C((70)) + + B --> D((20)) + B --> E((40)) + + C --> F((60)) + C --> G((80)) +``` + +
+ +### Balance Property + +For every node: + +```text +|Height(Left Subtree) - Height(Right Subtree)| ≤ 1 +``` + +## Height of a Node + +The height of a node is the number of edges in the longest path from that node to a leaf. + +Example: + +
+ +```mermaid +graph TD + A((30)) --> B((20)) + A --> C((40)) + B --> D((10)) +``` + +
+ +Heights: + +```text +10 → 0 +20 → 1 +40 → 0 +30 → 2 +``` + +## Balance Factor + +The balance factor determines whether a node is balanced. + +### Formula + +```text +Balance Factor = Height(Left Subtree) - Height(Right Subtree) +``` + +Possible balanced values: + +```text +-1, 0, +1 +``` + +Unbalanced: + +```text +<-1 or >+1 +``` + +### Example + +
+ +```mermaid +graph TD + A((30)) --> B((20)) + A --> C((40)) +``` + +
+ +```text +BF(30) = 0 +``` + +
+ +```mermaid +graph TD + A((30)) --> B((20)) + A((30)) --> 0((_)) +``` + +
+ +```text +BF(30) = +1 +``` + +
+ +```mermaid +graph TD + A((30)) --> 0((_)) + A((30)) --> B((40)) +``` + +
+ +```text +BF(30) = -1 +``` + +
+ +```mermaid +graph TD + A((30)) --> 0((_)) + A((30)) --> B((20)) + B --> C((10)) + B --> 1((_)) +``` + +
+ +```text +BF(30) = +2 +``` + +Node 30 is unbalanced. + +## Rotations + +AVL Trees use rotations to restore balance. + +There are four possible imbalance cases: + +1. Left-Left (LL) +2. Right-Right (RR) +3. Left-Right (LR) +4. Right-Left (RL) + +### Left-Left (LL) Case + +Occurs when: + +```text +Node becomes left-heavy +Insertion occurs in left subtree of left child +``` + +Example: + +Insert: + +```text +30, 20, 10 +``` + +Before balancing: + +
+ +```mermaid +graph TD + A((30)) --> B((20)) + A --> D((_)) + B --> C((10)) + B --> E((_)) +``` + +
+ +Balance Factor: + +```text +BF(30) = +2 +``` + +Perform a **Right Rotation**. + +After balancing: + +
+ +```mermaid +graph TD + A((20)) --> B((10)) + A --> C((30)) +``` + +
+ +#### Right Rotation + +Before: + +
+ +```mermaid +graph TD + Z((10)) --> A((_)) + Z --> Y((20)) + Y --> B((_)) + Y --> X((30)) +``` + +
+ +After: + +
+ +```mermaid +graph TD + Y((20)) --> X((10)) + Y --> Z((30)) +``` + +
+ +### Right-Right (RR) Case + +Occurs when: + +```text +Node becomes right-heavy +Insertion occurs in right subtree of right child +``` + +Example: + +Insert: + +```text +10, 20, 30 +``` + +Before balancing: + +
+ +```mermaid +graph TD + A((30)) --> B((20)) + A --> D((_)) + B --> C((10)) + B --> E((_)) +``` + +
+ +Balance Factor: + +```text +BF(10) = -2 +``` + +Perform a **Left Rotation**. + +After balancing: + +
+ +```mermaid +graph TD + Y((20)) --> X((10)) + Y --> Z((30)) +``` + +
+ +#### Left Rotation + +Before: + +
+ +```mermaid +graph TD + Z((z)) --> Y((y)) + Y --> X((x)) +``` + +
+ +After: + +
+ +```mermaid +graph TD + Y((y)) --> Z((z)) + Y --> X((x)) +``` + +
+ +### Left-Right (LR) Case + +Occurs when: + +```text +Node becomes left-heavy +Insertion occurs in right subtree of left child +``` + +Insert: + +```text +30, 10, 20 +``` + +Before balancing: + +
+ +```mermaid +graph TD + A((30)) --> B((10)) + B --> C((20)) +``` + +
+ +#### Step 1: Left Rotation on 10 + +
+ +```mermaid +graph TD + A((30)) --> B((20)) + B --> C((10)) +``` + +
+ +#### Step 2: Right Rotation on 30 + +
+ +```mermaid +graph TD + A((20)) --> B((10)) + A --> C((30)) +``` + +
+ +### Right-Left (RL) Case + +Occurs when: + +```text +Node becomes right-heavy +Insertion occurs in left subtree of right child +``` + +Insert: + +```text +10, 30, 20 +``` + +Before balancing: + +
+ +```mermaid +graph TD + A((10)) --> B((30)) + B --> C((20)) +``` + +
+ +#### Step 1: Right Rotation on 30 + +
+ +```mermaid +graph TD + A((10)) --> B((20)) + B --> C((30)) +``` + +
+ +#### Step 2: Left Rotation on 10 + +
+ +```mermaid +graph TD + A((20)) --> B((10)) + A --> C((30)) +``` + +
+ +### Summary of Rotations + +| Case | Condition | Fix | +| ---- | -------------- | ------------------------------ | +| LL | Left of Left | Right Rotation | +| RR | Right of Right | Left Rotation | +| LR | Right of Left | Left Rotation + Right Rotation | +| RL | Left of Right | Right Rotation + Left Rotation | + +## AVL Tree Insertion + +### Step 1 + +Insert the node exactly as in a BST. + +Example: + +
+ +```mermaid +graph TD + A((50)) --> B((30)) + A --> C((70)) + B --> D((20)) +``` + +
+ +### Step 2 + +Move upward from the inserted node toward the root. + +Update: + +```text +Height +Balance Factor +``` + +### Step 3 + +Check for imbalance. + +```text +Balance Factor > 1 +Balance Factor < -1 +``` + +### Step 4 + +Apply the appropriate rotation. + +```text +LL → Right Rotation +RR → Left Rotation +LR → Left Rotation + Right Rotation +RL → Right Rotation + Left Rotation +``` + +## AVL Tree Deletion + +Deletion follows normal BST deletion first. + +### BST Deletion Cases + +#### Leaf Node + +
+ +```mermaid +graph TD + A((30)) --> B((20)) + A --> C((40)) +``` + +
+ +Delete: + +```text +20 +``` + +#### One Child + +
+ +```mermaid +graph TD + A((30)) --> B((20)) + B --> C((10)) +``` + +
+ +Delete: + +```text +20 +``` + +Promote 10. + +#### Two Children + +Replace the node with: + +```text +Inorder Successor +or +Inorder Predecessor +``` + +Then delete the replacement node. + +### Rebalancing After Deletion + +Unlike insertion, deletion may cause multiple ancestors to become unbalanced. + +Therefore: + +```text +Delete Node +Update Heights +Update Balance Factors +Rotate If Needed +Continue Toward Root +``` + +## AVL Height Analysis + +AVL Trees guarantee logarithmic height. + +Minimum number of nodes required for a given height follows: + +```text +N(h) = 1 + N(h-1) + N(h-2) +``` + +This recurrence is similar to Fibonacci numbers. + +Therefore: + +```text +Height = O(log n) +``` + +More precisely: + +```text +Height ≤ 1.44 log₂(n + 2) +``` + +## Time Complexity + +| Operation | Complexity | +| ------------ | ---------- | +| Search | O(log n) | +| Insert | O(log n) | +| Delete | O(log n) | +| Find Minimum | O(log n) | +| Find Maximum | O(log n) | + +## Space Complexity + +Tree Storage: + +```text +O(n) +``` + +Extra per node: + +```text +Value +Left Pointer +Right Pointer +Height +``` + +## AVL Node Structure + +```text +Node +├── value +├── left +├── right +└── height +``` + +Example: + +
+ +```mermaid +graph TD + A(("30 (h=2)")) --> B(("20 (h=1)")) + A --> C(("40 (h=0)")) + B --> D(("10 (h=0)")) +``` + +
+ +## AVL Tree vs BST + +| Feature | BST | AVL | +| -------------- | ---- | ------------ | +| Self Balancing | No | Yes | +| Worst Height | O(n) | O(log n) | +| Search | O(n) | O(log n) | +| Insert | O(n) | O(log n) | +| Delete | O(n) | O(log n) | +| Extra Memory | No | Height Field | + +## AVL Tree vs Red-Black Tree + +| Feature | AVL | Red-Black | +| ------------- | ------------------ | ----------------------- | +| Balancing | Strict | Relaxed | +| Search Speed | Faster | Slightly Slower | +| Rotations | More | Fewer | +| Insert/Delete | Slower | Faster | +| Use Case | Read-Heavy Systems | General-Purpose Systems | + +## Advantages + +- Guaranteed O(log n) search. +- Prevents skewed trees. +- Faster lookups than Red-Black Trees. +- Strict balancing. +- Predictable performance. + +## Disadvantages + +- More complex implementation. +- Additional memory for height. +- More rotations during updates. +- Insertions and deletions can be slower than Red-Black Trees. + +## Key Takeaways + +- AVL Tree is a self-balancing Binary Search Tree. +- Every node maintains a balance factor. +- Balance Factor = Height(Left) − Height(Right). +- Allowed balance factors are -1, 0, and +1. +- Rotations restore balance after insertions and deletions. +- Four rotation cases exist: LL, RR, LR, and RL. +- AVL Trees guarantee O(log n) height. +- Search, insertion, and deletion all run in O(log n) time. diff --git a/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/introduction.md b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/introduction.md new file mode 100644 index 00000000..dbf88516 --- /dev/null +++ b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/introduction.md @@ -0,0 +1,36 @@ +--- +sidebar_position: 1 +--- + +# Introduction + +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + +A Self-Balancing Binary Search Tree (Self-Balancing BST) is a Binary Search Tree that automatically maintains a balanced structure after insertions and deletions. + +A standard Binary Search Tree can become unbalanced over time. For example, inserting values in sorted order can produce a skewed tree: + +```text +10 + \ + 20 + \ + 30 + \ + 40 +``` + +Although the tree still satisfies the Binary Search Tree property, its height becomes **O(n)**, causing search, insertion, and deletion operations to degrade from **O(log n)** to **O(n)**. + +Self-balancing BSTs solve this problem by automatically reorganizing the tree whenever it becomes too unbalanced. This keeps the height of the tree proportional to **log n**, ensuring efficient performance. + +## Benefits + +- Guarantees a height of **O(log n)** +- Provides efficient search, insertion, and deletion operations +- Prevents performance degradation caused by skewed trees +- Suitable for large and frequently updated datasets diff --git a/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/red-black.md b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/red-black.md new file mode 100644 index 00000000..6a5b5e4d --- /dev/null +++ b/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/red-black.md @@ -0,0 +1,675 @@ +--- +sidebar_position: 3 +--- + +# Red-Black Tree + +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + +A Red-Black Tree is a self-balancing Binary Search Tree where every node contains an additional piece of information called a **color**. + +Each node is either: + +- Red +- Black + +The coloring rules ensure that the tree remains approximately balanced. + +## Why Do We Need Red-Black Trees? + +A normal BST can become skewed. + +### Balanced BST + +
+ +```mermaid +graph TD + A((40)) + A --> B((20)) + A --> C((60)) + B --> D((10)) + B --> E((30)) + C --> F((50)) + C --> G((70)) +``` + +
+ +Height = O(log n) + +### Skewed BST + +
+ +```mermaid +graph TD + A((10)) + A --> F((_)) + A --> B((20)) + B --> G((_)) + B --> C((30)) + C --> H((_)) + C --> D((40)) + D --> I((_)) + D --> E((50)) +``` + +
+ +Height = O(n) + +Red-Black Trees prevent such degeneration and keep the height bounded. + +## Properties of a Red-Black Tree + +Every valid Red-Black Tree must satisfy the following five properties. + +### Every Node is Either Red or Black + +Example: + +
+ +```mermaid +graph TD + A(("20 (Black)")) + A --> B(("10 (Red)")) + A --> C(("30 (Black)")) +``` + +
+ +### Root Must Be Black + +Valid: + +
+ +```mermaid +graph TD + A(("20 (Black)")) + A --> B(("10 (Red)")) + A --> C(("30 (Red)")) +``` + +
+ +Invalid: + +
+ +```mermaid +graph TD + A(("20 (Red)")) + A --> B(("10 (Black)")) + A --> C(("30 (Black)")) +``` + +
+ +Root cannot be red. + +### All NIL Leaves Are Black + +Instead of using actual null pointers conceptually, Red-Black Trees treat every missing child as a special NIL node. + +
+ +```mermaid +graph TD + A(("20 (Black)")) + A --> B(("10 (Red)")) + A --> C(("30 (Red)")) + + B --> D(("NIL (Black)")) + B --> E(("NIL (Black)")) + + C --> F(("NIL (Black)")) + C --> G(("NIL (Black)")) +``` + +
+ +### Red Node Cannot Have Red Children + +No two consecutive red nodes can appear on a path. + +Valid: + +
+ +```mermaid +graph TD + A(("20 (Black)")) + A --> B(("10 (Red)")) + A --> C(("30 (Black)")) + + B --> D(("5 (Black)")) + B --> E(("NIL (Black)")) +``` + +
+ +Invalid: + +
+ +```mermaid +graph TD + A(("20 (Black)")) + A --> B(("10 (Red)")) + A --> D(("_")) + B --> C(("5 (Red)")) + B --> E(("_")) +``` + +
+ +This is called a **Red-Red Violation**. + +### Every Path Must Have Same Number of Black Nodes + +The number of black nodes from any node to its descendant NIL leaves must be identical. + +This count is called the **Black Height**. + +Valid: + +
+ +```mermaid +graph TD + A(("20 (Black)")) + + A --> B(("10 (Red)")) + A --> C(("30 (Red)")) + + B --> D(("5 (Black)")) + B --> E(("15 (Black)")) + + C --> F(("25 (Black)")) + C --> G(("35 (Black)")) +``` + +
+ +All root-to-NIL paths contain the same number of black nodes. + +## Black Height + +Black Height (BH) is: + +> Number of black nodes from a node to any NIL leaf, excluding the starting node itself. + +Example: + +
+ +```mermaid +graph TD + A(("20 (Black)")) + A --> B(("10 (Red)")) + A --> E(("_")) + B --> C(("5 (Black)")) + B --> F(("_")) + C --> D(("NIL (Black)")) + C --> G(("_")) +``` + +
+ +For node 20: + +Path: + +```text +20 → 10 → 5 → NIL +``` + +Black nodes below 20: + +```text +5, NIL +``` + +BH(20) = 2 + +## Insertion in Red-Black Tree + +Insertion occurs in two phases. + +- **Phase 1**: Insert the node exactly like a BST. + +- **Phase 2**: Fix Red-Black property violations. + +### New Nodes Are Always Inserted Red + +Suppose we insert 15. + +
+ +```mermaid +graph TD + A(("20 (Black)")) + A --> B(("10 (Red)")) + A --> C(("30 (Black)")) + + B --> D(("15 (Red)")) +``` + +
+ +Immediately we have: + +```tetx +10 (Red) +| +15 (Red) +``` + +Red-Red violation. + +## Fixing Violations + +There are two major tools: + +1. Recoloring +2. Rotations + +### Case 1: Uncle is Red + +Initial tree: + +
+ +```mermaid +graph TD + G(("20 (Black)")) + + G --> P(("10 (Red)")) + G --> U(("30 (Red)")) + + P --> N(("5 (Red)")) + P --> M(("_")) +``` + +
+ +```text +Node = 5 +Parent = 10 +Uncle = 30 +``` + +Both Parent and Uncle are Red. + +#### Solution + +Recolor: + +```text +Parent -> Black +Uncle -> Black +Grandparent -> Red +``` + +Result: + +
+ +```mermaid +graph TD + G(("20 (Red)")) + + G --> P(("10 (Black)")) + G --> U(("30 (Black)")) + + P --> N(("5 (Red)")) + P --> M(("_")) +``` + +
+ +If grandparent becomes root, recolor it back to black. + +### Case 2: Uncle is Black + +Rotations are required. + +#### Left-Left (LL) Case + +Before insertion: + +
+ +```mermaid +graph TD + G(("30 (Black)")) + G --> P(("20 (Red)")) + G --> M(("_")) + P --> N(("10 (Red)")) + P --> Q(("_")) +``` + +
+ +Violation: + +Red node cannot have Red children. + +After right rotation: + +
+ +```mermaid +graph TD + P(("20 (Black)")) + + P --> N(("10 (Red)")) + P --> G(("30 (Red)")) +``` + +
+ +#### Right-Right (RR) Case + +Before: + +
+ +```mermaid +graph TD + G(("10 (Black)")) + G --> A(("_")) + G --> P(("20 (Red)")) + P --> B(("_")) + P --> N(("30 (Red)")) +``` + +
+ +#### Left Rotation + +After: + +
+ +```mermaid +graph TD + P(("20 (Black)")) + + P --> G(("10 (Red)")) + P --> N(("30 (Red)")) +``` + +
+ +#### Left-Right (LR) Case + +Before: + +
+ +```mermaid +graph TD + G(("30 (Black)")) + + G --> P(("10 (Red)")) + G --> A(("_")) + + P --> B(("_")) + P --> N(("20 (Red)")) + +``` + +
+ +##### Step 1: Left Rotation + +
+ +```mermaid +graph TD + G(("30 (Black)")) + G --> P(("20 (Red)")) + G --> M(("_")) + P --> N(("10 (Red)")) + P --> Q(("_")) +``` + +
+ +##### Step 2: Right Rotation + +
+ +```mermaid +graph TD + N(("20 (Black)")) + + N --> P(("10 (Red)")) + N --> G(("30 (Red)")) +``` + +
+ +#### Right-Left (RL) Case + +Before: + +
+ +```mermaid +graph TD + G(("10 (Black)")) + + G --> A(("_")) + G --> P(("30 (Red)")) + + P --> N(("20 (Red)")) + P --> B(("_")) +``` + +
+ +##### Step 1: Right Rotation + +
+ +```mermaid +graph TD + G(("10 (Black)")) + G --> A(("_")) + G --> P(("20 (Red)")) + P --> B(("_")) + P --> N(("30 (Red)")) +``` + +
+ +##### Step 2: Left Rotation + +
+ +```mermaid +graph TD + N(("20 (Black)")) + + N --> G(("10 (Red)")) + N --> P(("30 (Red)")) +``` + +
+ +## Tree Rotations + +Rotations are local restructuring operations that preserve BST ordering. + +### Right Rotation + +Before: + +
+ +```mermaid +graph TD + G(("30 (Black)")) + G --> P(("20 (Red)")) + G --> M(("_")) + P --> N(("10 (Red)")) + P --> Q(("_")) +``` + +
+ +After: + +
+ +```mermaid +graph TD + X((20)) + X --> A((10)) + X --> Y((30)) +``` + +
+ +### Left Rotation + +Before: + +
+ +```mermaid +graph TD + X((20)) + X --> A(("_")) + X --> Y((30)) + Y --> Z(("_")) + Y --> B((40)) +``` + +
+ +After: + +
+ +```mermaid +graph TD + Y((30)) + Y --> X((20)) + Y --> B((40)) +``` + +
+ +## Example Insertion Sequence + +Insert: + +```text +10, 20, 30 +``` + +### Insert 10 + +
+ +```mermaid +graph TD + A(("10 (Black)")) +``` + +
+ +### Insert 20 + +
+ +```mermaid +graph TD + A(("10 (Black)")) + A --> Z(("_")) + A --> B(("20 (Red)")) +``` + +
+ +Valid. + +### Insert 30 + +
+ +```mermaid +graph TD + A(("10 (Black)")) + A --> X(("_")) + A --> B(("20 (Red)")) + B --> Y(("_")) + B --> C(("30 (Red)")) +``` + +
+ +RR violation. + +Apply left rotation: + +
+ +```mermaid +graph TD + B(("20 (Black)")) + B --> A(("10 (Red)")) + B --> C(("30 (Red)")) +``` + +
+ +Balanced again. + +## Deletion in Red-Black Tree + +Deletion is significantly more complicated than insertion. + +Process: + +1. Delete node as BST. +2. If a red node is removed → usually no problem. +3. If a black node is removed → black-height may decrease. +4. Fix violations using: + - Recoloring + - Rotations + - Double Black resolution + +Because deletion involves many cases, most implementations follow the CLRS algorithm or library implementations directly. + +## Red-Black Tree vs AVL Tree + +| Feature | Red-Black Tree | AVL Tree | +| ---------- | --------------- | ----------- | +| Balance | Looser | Stricter | +| Height | Slightly Taller | Shorter | +| Search | Slightly Slower | Faster | +| Insertion | Faster | Slower | +| Deletion | Faster | Slower | +| Rotations | Fewer | More | +| Complexity | Easier | More Strict | + +## Complexity of Operations + +| Operation | Complexity | +| --------- | ---------- | +| Search | O(log n) | +| Insert | O(log n) | +| Delete | O(log n) | +| Min | O(log n) | +| Max | O(log n) | diff --git a/docs/data-structure-and-algorithms/data-structures/tree/strict-binary-tree.md b/docs/data-structure-and-algorithms/data-structures/tree/strict-binary-tree.md index f7cf0a76..30588bc4 100644 --- a/docs/data-structure-and-algorithms/data-structures/tree/strict-binary-tree.md +++ b/docs/data-structure-and-algorithms/data-structures/tree/strict-binary-tree.md @@ -4,6 +4,12 @@ sidebar_position: 3 # Strict Binary Tree +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + A **Strict Binary Tree** (also called a full binary tree) is a binary tree in which every internal node has exactly two children. This means: - No node has only one child. diff --git a/docs/data-structure-and-algorithms/data-structures/tree/strict-vs-complete-binary-tree.md b/docs/data-structure-and-algorithms/data-structures/tree/strict-vs-complete-binary-tree.md index e8c3ca97..488dbed8 100644 --- a/docs/data-structure-and-algorithms/data-structures/tree/strict-vs-complete-binary-tree.md +++ b/docs/data-structure-and-algorithms/data-structures/tree/strict-vs-complete-binary-tree.md @@ -4,7 +4,11 @@ sidebar_position: 7 # Strict vs Complete Binary Tree - +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: ## Strict Binary Tree diff --git a/docs/data-structure-and-algorithms/data-structures/tree/tree-representation.md b/docs/data-structure-and-algorithms/data-structures/tree/tree-representation.md index 9264ea37..a6885539 100644 --- a/docs/data-structure-and-algorithms/data-structures/tree/tree-representation.md +++ b/docs/data-structure-and-algorithms/data-structures/tree/tree-representation.md @@ -4,7 +4,11 @@ sidebar_position: 5 # Tree Representation in Memory - +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: A tree can be stored in memory mainly in two ways: diff --git a/docs/data-structure-and-algorithms/data-structures/tree/tree-traversal.md b/docs/data-structure-and-algorithms/data-structures/tree/tree-traversal.md index b1e2ea6f..53f35de2 100644 --- a/docs/data-structure-and-algorithms/data-structures/tree/tree-traversal.md +++ b/docs/data-structure-and-algorithms/data-structures/tree/tree-traversal.md @@ -4,6 +4,12 @@ sidebar_position: 8 # Binary Tree Traversals +:::tip[Status] + +This note is complete, reviewed, and considered stable. + +::: + Traversal refers to visiting each node of a binary tree exactly once in a systematic way. There are two main categories: diff --git a/docs/intro.md b/docs/intro.md index c71453a6..18b2c282 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -156,19 +156,41 @@ If you come across any issues or errors in the notes, feel free to open an issue ### Data Structure and Algorithms -1. [Data Structure and Algorithms](/docs/data-structure-and-algorithms/introduction.md) - 1. [Data Structures](/docs/data-structure-and-algorithms/data-structures/introduction.md) +1. [Data Structure and Algorithms](/docs/data-structure-and-algorithms/introduction.md) + 1. [Data Structures](/docs/data-structure-and-algorithms/data-structures/introduction.md) 1. [Introduction](/docs/data-structure-and-algorithms/data-structures/introduction.md) 2. [Arrays](/docs/data-structure-and-algorithms/data-structures/arrays.md) 3. [Hash Table](/docs/data-structure-and-algorithms/data-structures/hash-table.md) 4. [Stack](/docs/data-structure-and-algorithms/data-structures/stack.md) 5. [Queue](/docs/data-structure-and-algorithms/data-structures/queue.md) - 1. [Algorithms](/docs/data-structure-and-algorithms/algorithms/introduction.md) + 6. [Tree](/docs/data-structure-and-algorithms/data-structures/tree/introduction.md) + 1. [Introduction](/docs/data-structure-and-algorithms/data-structures/tree/introduction.md) + 2. [Binary Tree](/docs/data-structure-and-algorithms/data-structures/tree/binary-tree.md) + 3. [Strict Binary Tree](/docs/data-structure-and-algorithms/data-structures/tree/strict-binary-tree.md) + 4. [N-ary Tree](/docs/data-structure-and-algorithms/data-structures/tree/n-ary-tree.md) + 5. [Tree Representation](/docs/data-structure-and-algorithms/data-structures/tree/tree-representation.md) + 6. [Full vs Complete Binary Tree](/docs/data-structure-and-algorithms/data-structures/tree/full-vs-complete-binary-tree.md) + 7. [Strict vs Complete Binary Tree](/docs/data-structure-and-algorithms/data-structures/tree/strict-vs-complete-binary-tree.md) + 8. [Binary Tree Travarsals](/docs/data-structure-and-algorithms/data-structures/tree/tree-traversal.md) + 9. [Common Tree Algorithms](/docs/data-structure-and-algorithms/data-structures/tree/common-algorithms.md) + 10. [Search Tree](/docs/data-structure-and-algorithms/data-structures/tree/search-tree/introduction.md) + 1. [Introduction](/docs/data-structure-and-algorithms/data-structures/tree/search-tree/introduction.md) + 2. [Binary Search Tree](/docs/data-structure-and-algorithms/data-structures/tree/search-tree/bst/introduction.md) + 1. [Introduction](/docs/data-structure-and-algorithms/data-structures/tree/search-tree/bst/introduction.md) + 2. [Common BST Algorithms](/docs/data-structure-and-algorithms/data-structures/tree/search-tree/bst/key-operations.md) + 3. [Self-Balancing Tree](/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/introduction.md) + 1. [Introduction](/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/introduction.md) + 2. [AVL Tree](/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/avl.md) + 3. [Red-Black Tree](/docs/data-structure-and-algorithms/data-structures/tree/search-tree/self-balancing-bst/red-black.md) + 4. [Prefix Search Tree](/docs/data-structure-and-algorithms/data-structures/tree/search-tree/prefix-search-tree/introduction.md) + 1. [Introduction](/docs/data-structure-and-algorithms/data-structures/tree/search-tree/prefix-search-tree/introduction.md) + 2. [Trie](/docs/data-structure-and-algorithms/data-structures/tree/search-tree/prefix-search-tree/trie.md) + 1. [Algorithms](/docs/data-structure-and-algorithms/algorithms/introduction.md) 1. [Introduction](/docs/data-structure-and-algorithms/algorithms/introduction.md) 2. [Recursion](/docs/data-structure-and-algorithms/algorithms/recursion.md) 3. [Sliding Window](/docs/data-structure-and-algorithms/algorithms/sliding-window.md) 4. [Two Pointers](/docs/data-structure-and-algorithms/algorithms/two-pointers.md) - 3. [Sorting](/docs/data-structure-and-algorithms/algorithms/sorting.md) + 5. [Sorting](/docs/data-structure-and-algorithms/algorithms/sorting.md) 1. [Time and Space Complexity](/docs/data-structure-and-algorithms/introduction.md) ### Operating Systems