ScholarQuill logoScholarQuillUniversity Notes
My Semester
Explore Notes
Past Papers12 New
Video CoursesNew
Search
Settings
Study Tools
GPA/CGPA Calculator
Schedule & To-Do
Student Portal
Contact
Contact
ScholarQuill logo
My Semester
Explore Notes
Past Papers12 New
Video CoursesNew
Search
Settings
GPA/CGPA Calculator
Schedule & To-Do
Student Portal
Contact
ScholarQuill logoScholarQuillUniversity Notes
Study PortalCC-213Balanced Trees
Ctrl + K
Login
Explore
Search
Semester
Papers
CGPA
    CC-213

    Data Structures & Algorithms

    Progress0 / 37 done
    Topics37
    1Abstract Data Types2Complexity Analysis3Big Oh Notation4Stacks (Linked Lists and Array Implementations)5Recursion and analyzing recursive algorithms6Divide and Conquer Algorithms7Sorting Algorithms8Selection Sort9Insertion Sort10Merge Sort11Quick Sort12Bubble Sort13Heap Sort14Shell Sort15Radix Sort16Bucket Sort17Queue18Dequeuer19Priority Queues (linked and array implementations of queues)20Linked List and Its Various Types21Sorted Linked List22Searching an Unsorted Array23Binary Search for Sorted Arrays24Hashing and Indexing25Open Addressing and Chaining26Trees and Tree Traversals27Binary Search Trees28Heaps29M-Way Trees30Balanced Trees31Graphs32Breadth-First Traversal33Depth-First Traversal34Topological Order35Shortest Path36Adjacency Matrix and Adjacency List Implementations37Memory Management and Garbage Collection
    6 min read
    Topic 30 of 37
    Topic Study Note Illustration
    30

    Balanced Trees

    Balanced trees are a category of data structures that maintain a balanced height across their nodes, ensuring that operations such as search, insertion, and deletion can be...

    Balanced Trees

    Balanced trees are a category of data structures that maintain a balanced height across their nodes, ensuring that operations such as search, insertion, and deletion can be performed efficiently. The primary goal of a balanced tree is to minimize the height of the tree to guarantee logarithmic time complexity for these operations.

    Key Characteristics

    1. Height-Balanced: A balanced tree ensures that the height of the left and right subtrees of any node differ by no more than a certain factor, typically one. This is crucial for maintaining performance.

    2. Logarithmic Time Complexity: Most operations, including search, insert, and delete, can be performed in O(log⁡n)O(\log n)O(logn) time, where nnn is the number of nodes in the tree.

    3. Self-Balancing: Balanced trees automatically adjust their structure during insertions and deletions to maintain balance.

    Common Types of Balanced Trees

    1. AVL Trees:

      • Named after inventors Adelson-Velsky and Landis.
      • Each node maintains a balance factor (the difference in height between the left and right subtrees).
      • Requires rotations to maintain balance after insertions or deletions.
    2. Red-Black Trees:

      • Each node is colored either red or black.
      • The tree satisfies specific properties that ensure balanced height and structure.
      • Operations involve color changes and rotations to maintain balance.
    3. B-Trees:

      • Generalized balanced search trees used in databases and file systems.
      • Nodes can have multiple keys and children.
      • B-trees remain balanced through a set of rules about node filling and splitting.

    Example: AVL Tree

    Let’s look at an implementation of an AVL Tree, focusing on insertion and rotation to maintain balance.

    AVL Tree Implementation

    #include <iostream>
    using namespace std;
    
    struct Node {
        int data;
        Node* left;
        Node* right;
        int height;
    
        Node(int val) : data(val), left(nullptr), right(nullptr), height(1) {}
    };
    
    class AVLTree {
    private:
        Node* root;
    
        int getHeight(Node* node) {
            return node ? node->height : 0;
        }
    
        int getBalance(Node* node) {
            return node ? getHeight(node->left) - getHeight(node->right) : 0;
        }
    
        Node* rotateRight(Node* y) {
            Node* x = y->left;
            Node* T2 = x->right;
    
            // Perform rotation
            x->right = y;
            y->left = T2;
    
            // Update heights
            y->height = max(getHeight(y->left), getHeight(y->right)) + 1;
            x->height = max(getHeight(x->left), getHeight(x->right)) + 1;
    
            return x; // New root
        }
    
        Node* rotateLeft(Node* x) {
            Node* y = x->right;
            Node* T2 = y->left;
    
            // Perform rotation
            y->left = x;
            x->right = T2;
    
            // Update heights
            x->height = max(getHeight(x->left), getHeight(x->right)) + 1;
            y->height = max(getHeight(y->left), getHeight(y->right)) + 1;
    
            return y; // New root
        }
    
        Node* insert(Node* node, int key) {
            if (!node) return new Node(key);
    
            if (key < node->data)
                node->left = insert(node->left, key);
            else if (key > node->data)
                node->right = insert(node->right, key);
            else // Duplicate keys not allowed
                return node;
    
            // Update height
            node->height = 1 + max(getHeight(node->left), getHeight(node->right)));
    
            // Get balance factor
            int balance = getBalance(node);
    
            // Perform rotations if needed
            // Left Left Case
            if (balance > 1 && key < node->left->data)
                return rotateRight(node);
    
            // Right Right Case
            if (balance < -1 && key > node->right->data)
                return rotateLeft(node);
    
            // Left Right Case
            if (balance > 1 && key > node->left->data) {
                node->left = rotateLeft(node->left);
                return rotateRight(node);
            }
    
            // Right Left Case
            if (balance < -1 && key < node->right->data) {
                node->right = rotateRight(node->right);
                return rotateLeft(node);
            }
    
            return node; // Return unchanged node
        }
    
        void inOrder(Node* node) {
            if (node) {
                inOrder(node->left);
                cout << node->data << " ";
                inOrder(node->right);
            }
        }
    
    public:
        AVLTree() : root(nullptr) {}
    
        void insert(int key) {
            root = insert(root, key);
        }
    
        void inOrder() {
            inOrder(root);
            cout << endl;
        }
    };
    
    int main() {
        AVLTree tree;
        tree.insert(10);
        tree.insert(20);
        tree.insert(30); // Causes a left rotation
    
        cout << "In-order Traversal: ";
        tree.inOrder(); // Output: 10 20 30
    
        return 0;
    }
    

    Explanation of the Code

    1. Node Structure: Each node contains data, pointers to left and right children, and the height of the node.
    2. AVLTree Class:
      • Height and Balance: Functions to get the height of a node and calculate its balance factor.
      • Rotations: Methods for right and left rotations to maintain balance.
      • Insert Function: Recursively inserts a new key and performs rotations if the tree becomes unbalanced.
      • In-Order Traversal: Prints the keys in sorted order.

    Complexity Analysis

    • Search: O(log⁡n)O(\log n)O(logn)
    • Insertion: O(log⁡n)O(\log n)O(logn)
    • Deletion: O(log⁡n)O(\log n)O(logn)
    • Space Complexity: O(n)O(n)O(n) for storing nodes.

    Applications of Balanced Trees

    1. Databases: Used in indexing and quick retrieval of records.
    2. Memory Management: Used in systems that manage free and occupied memory spaces.
    3. Dynamic Sets: Implemented in various data structures for dynamic set operations.

    Conclusion

    Balanced trees, such as AVL and Red-Black trees, are essential for maintaining efficient performance in dynamic data management. By keeping the tree balanced, they ensure that operations remain efficient, making them invaluable in various applications, particularly in databases and systems requiring quick data retrieval. Understanding balanced trees equips you with the tools to design efficient algorithms and data structures.

    ← Previous topic 29
    M-Way Trees
    Next topic 31 →
    Graphs

    Past Papers

    Open this section to view and download past papers

    Click on Show Past Papers to load available exam papers.

    Reading Progress
    0%
    6mremaining
    940words
    Intermediatelevel
    On This Page

    No headings found

    Study Toolkit

    Subject Portal

    Data Structures & Algorithms