Trees (binary tree, binary search tree, segment tree, etc.)

Trees are one of the most widely used data structures in computer science. They are hierarchical structures that allow efficient storage and retrieval of data. In this article, we will explore various types of trees, such as a binary tree, binary search tree, and segment tree, and their applications in competitive programming using C++.

Binary Tree

A binary tree is a special type of tree where each node can have at most two children, known as the left child and the right child. It is a recursive data structure that is defined using a node and its children, recursively.

Representation of Binary Tree

In C++, we can represent a binary tree using a class or a struct. Each node contains a value and two pointers to its left and right children. Here's an example of a binary tree node:

struct Node {
    int data;
    Node* left;
    Node* right;
};

Traversing Binary Trees

There are three common ways to traverse binary trees: in-order, pre-order, and post-order traversal.

  1. In-order traversal: In this traversal, we first visit the left subtree, then the root node, and finally the right subtree. This traversal results in nodes being visited in ascending order in a binary search tree.

  2. Pre-order traversal: In this traversal, we first visit the root node, then the left subtree, and finally the right subtree.

  3. Post-order traversal: In this traversal, we first visit the left subtree, then the right subtree, and finally the root node.

Traversing a binary tree can be done using a recursive approach or an iterative approach using stacks or queues.

Binary Search Tree (BST)

A binary search tree is a binary tree with additional properties. It maintains the binary search property, which states that for any node, the values in its left subtree are less than the node's value, and the values in its right subtree are greater than the node's value.

BST is efficient for searching, insertion, and deletion operations. The time complexity for these operations is O(log N) on average, with O(N) as the worst-case time complexity if the tree is highly unbalanced.

Operations on Binary Search Tree

BST supports several key operations:

  • Insertion: To insert a value into a BST, we compare the value with the current node's value. If it is smaller, we go to the left subtree, and if it is larger, we go to the right subtree. We repeat this process until we find an empty spot to insert the new node.

  • Searching: To search for a value in a BST, we start from the root and compare the value with the current node's value. If it matches, we return the node. If it is smaller, we go to the left subtree, and if it is larger, we go to the right subtree. We repeat this process until we find the value or reach a NULL node.

  • Deletion: To delete a node from a BST, we have three cases to consider: deleting a leaf node, deleting a node with one child, and deleting a node with two children. The deletion process involves finding the node to delete, rearranging the tree, and updating the pointers accordingly.

Segment Tree

A segment tree is a binary tree data structure used for storing and querying intervals or segments. It is mainly used for handling range-based queries efficiently.

Construction of Segment Tree

The construction of a segment tree involves dividing the array into smaller segments until we reach the base case of a single element. Each node in the segment tree represents an interval of the array, and the value of the node can be calculated based on the values of its left and right children.

Operations on Segment Tree

Segment trees support several operations:

  • Build: To construct a segment tree, we start with the given array and recursively divide it into smaller segments until we reach the base case. We calculate the value of each node based on the values of its children.

  • Update: To update a value in the array, we traverse the segment tree and update the corresponding nodes based on the changes in the array. This process involves visiting a logarithmic number of nodes in the worst case.

  • Query: To perform a query on an interval, we traverse the segment tree and return the result based on the values stored in the tree. This process also involves visiting a logarithmic number of nodes in the worst case.

Segment trees are frequently used in various algorithms and data structures, such as range-based minimum/maximum queries, sum of a range, and finding the number of elements less than or equal to a given value in a range.

Conclusion

Trees are versatile data structures that are used in a wide range of applications in computer science. In competitive programming using C++, understanding different types of trees, such as binary trees, binary search trees, and segment trees, can help you solve complex problems efficiently.


noob to master © copyleft