Queries for DFS of a subtree in a tree

Given a tree of N nodes and N-1 edges. The task is to print the DFS of the subtree of a given node for multiple queries. The DFS must include the given node as the root of the subtree.

In the above tree, if 1 is given as the node, then the DFS of subtree will be 1 2 4 6 7 5 3.

If 2 is given as the node, then the DFS of the subtree will be 2 4 6 7 5..

Approach:

  • Add the edges between the nodes in an adjacency list.
  • Call DFS function to generate the DFS of the complete tree.
  • Use a under[] array to store the height of the subtree under the given node including the node.
  • In the DFS function, keep incrementing the size of subtree on every recursive call.
  • Mark the node index in the DFS of complete using hashing.
  • The DFS of a subtree of a node will always be a contigous subarray starting from the node(say index ind) to (ind+height of subtree).
  • Get the index of node which has been stored using hashing and print the nodes from original DFS till index = ind + heigth of subtree which has been stored in under[node].

Below is the implementation of the above approach.

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for Queries
// for DFS of subtree of a node in a tree
#include <bits/stdc++.h>
using namespace std;
const int N = 100000;
  
// Adjaceny list to store the
// tree nodes connection
vector<int> v[N];
  
// stores the index of node in DFS
unordered_map<int, int> mp;
  
// stores the index of node in
// original node
vector<int> a;
  
// Function to call DFS and count nodes
// under that subtree
void dfs(int under[], int child, int parent)
{
  
    // stores the DFS of tree
    a.push_back(child);
  
    // hieght of subtree
    under[child] = 1;
  
    // iterate for children
    for (auto it : v[child]) {
  
        // if not equal to parent
        // so that it does not traverse back
        if (it != parent) {
  
            // call DFS for subtree
            dfs(under, it, child);
  
            // add the heigth
            under[child] += under[it];
        }
    }
}
  
// Function to print the DFS of subtree of nodec
void printDFSofSubtree(int node, int under[])
{
    // index of node in the original DFS
    int ind = mp[node];
  
    // height of subtree of node
    int height = under[node];
  
    cout << "The DFS of subtree " << node << ": ";
  
    // print the DFS of subtree
    for (int i = ind; i < ind + under[node]; i++) {
        cout << a[i] << " ";
    }
    cout << endl;
}
  
// Function to add edges to a tree
void addEdge(int x, int y)
{
    v[x].push_back(y);
    v[y].push_back(x);
}
  
// Marks the index of node in original DFS
void markIndexDfs()
{
    int size = a.size();
  
    // marks the index
    for (int i = 0; i < size; i++) {
        mp[a[i]] = i;
    }
}
  
// Driver Code
int main()
{
    int n = 7;
  
    // add edges of a tree
    addEdge(1, 2);
    addEdge(1, 3);
    addEdge(2, 4);
    addEdge(2, 5);
    addEdge(4, 6);
    addEdge(4, 7);
  
    // array to store the height of subtree
    // of every node in a tree
    int under[n + 1];
  
    // Call the function DFS to generate the DFS
    dfs(under, 1, 0);
  
    // Function call to mark the index of node
    markIndexDfs();
  
    // Query 1
    printDFSofSubtree(2, under);
  
    // Query 1
    printDFSofSubtree(4, under);
  
    return 0;
}

chevron_right


Time Complexity: O( N + M ), where N is the number of nodes and M is the number of edges for pre-calculation and O(N) for queries in worst case.
Auxiliary Space: O(N)



My Personal Notes arrow_drop_up


Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.