Open In App

Count distinct element in a BST

Last Updated : 20 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary search tree (BST), the task is to count the number of distinct elements present in it.

Examples:

Input:

       5
    /     \ 
  3       7
 /  \    /   \ 
2  4   6   8
Output : 7
Explanation: The distinct elements in the above BST are {2, 3, 4, 5, 6, 7, 8}.

Input:

         8
      /     \ 
    5     15
  / \     /    \ 
5  7 12    20
Output: 6
Explanation: The distinct elements in the above BST are {5, 7, 8, 12, 15, 20}.

Count distinct elements in a BST using In-order Traversal

The idea is to perform an in-order traversal of the tree, and for each node we visit, we can check if it is distinct from the previously visited node. For this, we can maintain a variable to store the value of the previously visited node, and compare it with the value of the current node.

Below are the steps for the above approach:

  • Perform an in-order traversal of the BST, and for each node visited, check if it is distinct from the previously visited node.
  • For the first node visited, set the previously visited node value to the minimum possible value in the BST (which will be INT_MIN).
  • If the current node value is different from the previously visited node value, increment the count of distinct elements by 1 and update the value of the previously visited node to the current node value.
  • After the traversal is complete, return the count of distinct elements.

Below is the code for the above approach:

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
// BST node structure
struct Node {
    int data;
    Node *left, *right;
    Node(int val)
    {
        data = val;
        left = right = NULL;
    }
};
 
// Function to count distinct
// elements in a BST
int countDistinct(Node* root)
{
 
    // Initialize count to 0
    int count = 0;
 
    // Initialize previously visited
    // node value to -infinity
    int prev = INT_MIN;
 
    // Handle empty BST
    // perform in-order traversal
    if (root == NULL)
        return 0;
    while (root != NULL) {
 
        // If left child is null, visit
        // current node and move
        // to right child
        if (root->left == NULL) {
            if (root->data != prev) {
                count++;
                prev = root->data;
            }
            root = root->right;
        }
        else {
 
            // Find inorder predecessor
            Node* curr = root->left;
            while (curr->right != NULL
                   && curr->right != root) {
                curr = curr->right;
            }
 
            // If predecessor's right
            // child is null, set it to
            // current node and move to
            // left child
            if (curr->right == NULL) {
                curr->right = root;
                root = root->left;
            }
 
            // If predecessor's right
            // child is current node,
            // visit current node and
            // move to right child
            else {
                if (root->data != prev) {
                    count++;
                    prev = root->data;
                }
                curr->right = NULL;
                root = root->right;
            }
        }
    }
 
    // Return count of distinct elements
    return count;
}
 
// Driver code
int main()
{
 
    // Create a BST
    Node* root = new Node(5);
    root->left = new Node(3);
    root->left->left = new Node(2);
    root->left->right = new Node(4);
    root->right = new Node(7);
    root->right->left = new Node(6);
    root->right->right = new Node(8);
 
    // Count distinct elements
    int distinct = countDistinct(root);
    cout << "Distinct elements in BST: " << distinct
         << endl;
 
    return 0;
}


Java




import java.util.*;
 
// BST node structure
class Node {
    int data;
    Node left, right;
    Node(int val)
    {
        data = val;
        left = right = null;
    }
}
 
class Main {
 
    // Function to count distinct
    // elements in a BST
    static int countDistinct(Node root)
    {
 
        // Initialize count to 0
        int count = 0;
 
        // Initialize previously visited
        // node value to -infinity
        int prev = Integer.MIN_VALUE;
 
        // Handle empty BST
        // perform in-order traversal
        if (root == null)
            return 0;
        while (root != null) {
 
            // If left child is null, visit
            // current node and move
            // to right child
            if (root.left == null) {
                if (root.data != prev) {
                    count++;
                    prev = root.data;
                }
                root = root.right;
            }
            else {
 
                // Find inorder predecessor
                Node curr = root.left;
                while (curr.right != null
                       && curr.right != root) {
                    curr = curr.right;
                }
 
                // If predecessor's right
                // child is null, set it to
                // current node and move to
                // left child
                if (curr.right == null) {
                    curr.right = root;
                    root = root.left;
                }
 
                // If predecessor's right
                // child is current node,
                // visit current node and
                // move to right child
                else {
                    if (root.data != prev) {
                        count++;
                        prev = root.data;
                    }
                    curr.right = null;
                    root = root.right;
                }
            }
        }
 
        // Return count of distinct elements
        return count;
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        // Create a BST
        Node root = new Node(5);
        root.left = new Node(3);
        root.left.left = new Node(2);
        root.left.right = new Node(4);
        root.right = new Node(7);
        root.right.left = new Node(6);
        root.right.right = new Node(8);
 
        // Count distinct elements
        int distinct = countDistinct(root);
        System.out.println("Distinct elements in BST: "
                           + distinct);
    }
}


Python3




# Python 3 code for the above approach
 
# BST node structure
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None
 
# Function to count distinct elements in a BST
def countDistinct(root):
 
    # Initialize count to 0
    count = 0
 
    # Initialize previously visited
    # node value to -infinity
    prev = float('-inf')
 
    # Handle empty BST
    # perform in-order traversal
    if root is None:
        return 0
    while root is not None:
 
        # If left child is null, visit
        # current node and move
        # to right child
        if root.left is None:
            if root.data != prev:
                count += 1
                prev = root.data
            root = root.right
        else:
 
            # Find inorder predecessor
            curr = root.left
            while curr.right is not None and curr.right != root:
                curr = curr.right
 
            # If predecessor's right child is null, set it to
            # current node and move to left child
            if curr.right is None:
                curr.right = root
                root = root.left
 
            # If predecessor's right child is current node,
            # visit current node and move to right child
            else:
                if root.data != prev:
                    count += 1
                    prev = root.data
                curr.right = None
                root = root.right
 
    # Return count of distinct elements
    return count
 
# Driver code
if __name__ == '__main__':
 
    # Create a BST
    root = Node(5)
    root.left = Node(3)
    root.left.left = Node(2)
    root.left.right = Node(4)
    root.right = Node(7)
    root.right.left = Node(6)
    root.right.right = Node(8)
 
    # Count distinct elements
    distinct = countDistinct(root)
    print("Distinct elements in BST:", distinct)


C#




// C# code for the above approach
using System;
 
public class Node {
    public int data;
    public Node left, right;
    public Node(int val)
    {
        data = val;
        left = right = null;
    }
}
 
public class GFG {
    // Function to count distinct
    // elements in a BST
    static int CountDistinct(Node root)
    {
        // Initialize count to 0
        int count = 0;
 
        // Initialize previously visited
        // node value to -infinity
        int prev = int.MinValue;
 
        // Handle empty BST
        // perform in-order traversal
        if (root == null)
            return 0;
        while (root != null) {
            // If left child is null, visit
            // current node and move
            // to right child
            if (root.left == null) {
                if (root.data != prev) {
                    count++;
                    prev = root.data;
                }
                root = root.right;
            }
            else {
                // Find inorder predecessor
                Node curr = root.left;
                while (curr.right != null
                       && curr.right != root) {
                    curr = curr.right;
                }
 
                // If predecessor's right
                // child is null, set it to
                // current node and move to
                // left child
                if (curr.right == null) {
                    curr.right = root;
                    root = root.left;
                }
 
                // If predecessor's right
                // child is current node,
                // visit current node and
                // move to right child
                else {
                    if (root.data != prev) {
                        count++;
                        prev = root.data;
                    }
                    curr.right = null;
                    root = root.right;
                }
            }
        }
 
        // Return count of distinct elements
        return count;
    }
 
    // Driver code
    static void Main()
    {
        // Create a BST
        Node root = new Node(5);
        root.left = new Node(3);
        root.left.left = new Node(2);
        root.left.right = new Node(4);
        root.right = new Node(7);
        root.right.left = new Node(6);
        root.right.right = new Node(8);
 
        // Count distinct elements
        int distinct = CountDistinct(root);
        Console.WriteLine("Distinct elements in BST: "
                          + distinct);
    }
}
 
// This code is contributed by Susobhan Akhuli


Javascript




// JavaScript code for the above approach:
 
// BST node structure
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}
 
// Function to count distinct
// elements in a BST
function countDistinct(root) {
 
    // Initialize count to 0
    let count = 0;
     
    // Initialize previously visited
    // node value to -infinity
    let prev = -Infinity;
     
    // Handle empty BST
    // perform in-order traversal
    if (root === null)
        return 0;
    while (root !== null) {
     
        // If left child is null, visit
        // current node and move
        // to right child
        if (root.left === null) {
            if (root.data !== prev) {
                count++;
                prev = root.data;
            }
            root = root.right;
        }
        else {
     
            // Find inorder predecessor
            let curr = root.left;
            while (curr.right !== null
                   && curr.right !== root) {
                curr = curr.right;
            }
     
            // If predecessor's right
            // child is null, set it to
            // current node and move to
            // left child
            if (curr.right === null) {
                curr.right = root;
                root = root.left;
            }
     
            // If predecessor's right
            // child is current node,
            // visit current node and
            // move to right child
            else {
                if (root.data !== prev) {
                    count++;
                    prev = root.data;
                }
                curr.right = null;
                root = root.right;
            }
        }
    }
     
    // Return count of distinct elements
    return count;
}
 
// Driver code
function main() {
 
    // Create a BST
    let root = new Node(5);
    root.left = new Node(3);
    root.left.left = new Node(2);
    root.left.right = new Node(4);
    root.right = new Node(7);
    root.right.left = new Node(6);
    root.right.right = new Node(8);
     
    // Count distinct elements
    let distinct = countDistinct(root);
    console.log("Distinct elements in BST: " + distinct);
     
    return 0;
}
 
main();


Output

Distinct elements in BST: 7






Time Complexity: O(n) Where n is the number of nodes in the BST.
Auxiliary Space: O(1)

Count distinct elements in a BST using Recursive in-order traversal

This approach is to do an in-order traversal of the given BST in a recursive manner and keep maintaining the previous node value traversed in order to check if the current one has already occurred or not. This can be possible since inorder traversal gives sorted order of values of the nodes.

Below is the code for the above approach:

C++




// C++ code for the above approach:
 
#include <bits/stdc++.h>
using namespace std;
 
// BST node structure
struct Node {
    int data;
    Node *left, *right;
    Node(int val)
    {
        data = val;
        left = right = NULL;
    }
};
 
// Function to count distinct elements
// in a BST using recursive
// inorder traversal
void countDistinctUtil(Node* root, int& count, int& prev)
{
 
    // Base case
    if (root == NULL)
        return;
 
    // Recursively traverse the
    // left subtree
    countDistinctUtil(root->left, count, prev);
 
    // Check if the current node
    // is distinct
    if (root->data != prev) {
        count++;
        prev = root->data;
    }
 
    // Recursively traverse the
    // right subtree
    countDistinctUtil(root->right, count, prev);
}
 
// Function to count distinct elements
// in a BST using recursive
// inorder traversal
int countDistinct(Node* root)
{
 
    // Initialize count to 0
    int count = 0;
 
    // Initialize previously visited
    // node value to -infinity
    int prev = INT_MIN;
 
    // Call countDistinctUtil to count
    // distinct elements in the BST
    countDistinctUtil(root, count, prev);
 
    // Return count of distinct elements
    return count;
}
 
// Driver code
int main()
{
 
    // Create a BST
    Node* root = new Node(5);
    root->left = new Node(3);
    root->left->left = new Node(2);
    root->left->right = new Node(4);
    root->right = new Node(7);
    root->right->left = new Node(6);
    root->right->right = new Node(8);
 
    // Count distinct elements
    int distinct = countDistinct(root);
    cout << "Distinct elements in BST: " << distinct
         << endl;
 
    return 0;
}
 
// This code is contributed by Chandramani Kumar


Java




// Java code for the above approach
// Java code for the above approach:
class Node {
    int data;
    Node left, right;
    Node(int val)
    {
        data = val;
        left = right = null;
    }
}
 
public class GFG {
 
    // Function to count distinct elements
    // in a BST using recursive
    // inorder traversal
    static void countDistinctUtil(Node root, int[] count,
                                  int[] prev)
    {
 
        // Base case
        if (root == null)
            return;
 
        // Recursively traverse the
        // left subtree
        countDistinctUtil(root.left, count, prev);
 
        // Check if the current node
        // is distinct
        if (root.data != prev[0]) {
            count[0]++;
            prev[0] = root.data;
        }
 
        // Recursively traverse the
        // right subtree
        countDistinctUtil(root.right, count, prev);
    }
 
    // Function to count distinct elements
    // in a BST using recursive
    // inorder traversal
    static int countDistinct(Node root)
    {
 
        // Initialize count to 0
        int[] count = { 0 };
 
        // Initialize previously visited
        // node value to -infinity
        int[] prev = { Integer.MIN_VALUE };
 
        // Call countDistinctUtil to count
        // distinct elements in the BST
        countDistinctUtil(root, count, prev);
 
        // Return count of distinct elements
        return count[0];
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        // Create a BST
        Node root = new Node(5);
        root.left = new Node(3);
        root.left.left = new Node(2);
        root.left.right = new Node(4);
        root.right = new Node(7);
        root.right.left = new Node(6);
        root.right.right = new Node(8);
 
        // Count distinct elements
        int distinct = countDistinct(root);
        System.out.println("Distinct elements in BST: "
                           + distinct);
    }
}
 
// This code is contributed by Susobhan Akhuli


Python3




# Python code for the above approach
 
# BST node structure
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None
 
# Function to count distinct elements
# in a BST using recursive
# inorder traversal
def countDistinctUtil(root, count, prev):
 
    # Base case
    if root is None:
        return
 
    # Recursively traverse the
    # left subtree
    countDistinctUtil(root.left, count, prev)
 
    # Check if the current node
    # is distinct
    if root.data != prev[0]:
        count[0] += 1
        prev[0] = root.data
 
    # Recursively traverse the
    # right subtree
    countDistinctUtil(root.right, count, prev)
 
# Function to count distinct elements
# in a BST using recursive
# inorder traversal
def countDistinct(root):
 
    # Initialize count to 0
    count = [0]
 
    # Initialize previously visited
    # node value to -infinity
    prev = [float('-inf')]
 
    # Call countDistinctUtil to count
    # distinct elements in the BST
    countDistinctUtil(root, count, prev)
 
    # Return count of distinct elements
    return count[0]
 
# Driver code
if __name__ == '__main__':
 
    # Create a BST
    root = Node(5)
    root.left = Node(3)
    root.left.left = Node(2)
    root.left.right = Node(4)
    root.right = Node(7)
    root.right.left = Node(6)
    root.right.right = Node(8)
 
    # Count distinct elements
    distinct = countDistinct(root)
    print("Distinct elements in BST:", distinct)
 
# This code is contributed by Susobhan Akhuli


C#




// C# code for the above approach
using System;
 
// BST node structure
class Node {
    public int data;
    public Node left, right;
 
    public Node(int val)
    {
        data = val;
        left = right = null;
    }
}
 
public class GFG {
    // Function to count distinct elements
    // in a BST using recursive
    // inorder traversal
    static void CountDistinctUtil(Node root, ref int count,
                                  ref int prev)
    {
        // Base case
        if (root == null)
            return;
 
        // Recursively traverse the
        // left subtree
        CountDistinctUtil(root.left, ref count, ref prev);
 
        // Check if the current node
        // is distinct
        if (root.data != prev) {
            count++;
            prev = root.data;
        }
 
        // Recursively traverse the
        // right subtree
        CountDistinctUtil(root.right, ref count, ref prev);
    }
 
    // Function to count distinct elements
    // in a BST using recursive
    // inorder traversal
    static int CountDistinct(Node root)
    {
        // Initialize count to 0
        int count = 0;
 
        // Initialize previously visited
        // node value to -infinity
        int prev = int.MinValue;
 
        // Call CountDistinctUtil to count
        // distinct elements in the BST
        CountDistinctUtil(root, ref count, ref prev);
 
        // Return count of distinct elements
        return count;
    }
 
    static void Main()
    {
        // Create a BST
        Node root = new Node(5);
        root.left = new Node(3);
        root.left.left = new Node(2);
        root.left.right = new Node(4);
        root.right = new Node(7);
        root.right.left = new Node(6);
        root.right.right = new Node(8);
 
        // Count distinct elements
        int distinct = CountDistinct(root);
        Console.WriteLine("Distinct elements in BST: "
                          + distinct);
    }
}
 
// This code is contributed by Susobhan Akhuli


Javascript




// BST node structure
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}
 
// Function to count distinct elements in a BST using recursive inorder traversal
function countDistinct(root) {
    let count = 0;
    let prev = Number.MIN_SAFE_INTEGER;
 
    // Helper function to perform the inorder traversal
    function countDistinctUtil(node) {
        if (node === null) {
            return;
        }
 
        // Recursively traverse the left subtree
        countDistinctUtil(node.left);
 
        // Check if the current node is distinct
        if (node.data !== prev) {
            count++;
            prev = node.data;
        }
 
        // Recursively traverse the right subtree
        countDistinctUtil(node.right);
    }
 
    // Call the helper function to count distinct elements in the BST
    countDistinctUtil(root);
 
    return count;
}
 
// Driver code
function main() {
    // Create a BST
    const root = new Node(5);
    root.left = new Node(3);
    root.left.left = new Node(2);
    root.left.right = new Node(4);
    root.right = new Node(7);
    root.right.left = new Node(6);
    root.right.right = new Node(8);
 
    // Count distinct elements
    const distinct = countDistinct(root);
    console.log("Distinct elements in BST: " + distinct);
}
 
// Call the main function to execute the code
main();


Output

Distinct elements in BST: 7






Time Complexity: O(n) Where n is the number of nodes in the BST.
Auxiliary Space: O(h) where h is the depth of the BST. This is due to recursion stack space.

Related Articles:



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads