Queries to find distance between two nodes of a Binary tree | C ++ program to find distance between two nodes for multiple queries ; A tree node structure ; Utility function to create a new Binary Tree node ; Array to store level of each node ; Utility Function to store level of all nodes ; queue to hold tree node with level ; let root node be at level 0 ; Do level Order Traversal of tree ; Node p . first is on level p . second ; If left child exits , put it in queue with current_level + 1 ; If right child exists , put it in queue with current_level + 1 ; Stores Euler Tour ; index in Euler array ; Find Euler Tour ; store current node 's data ; If left node exists ; traverse left subtree ; store parent node 's data ; If right node exists ; traverse right subtree ; store parent node 's data ; checks for visited nodes ; Stores level of Euler Tour ; Stores indices of first occurrence of nodes in Euler tour ; Preprocessing Euler Tour for finding LCA ; If node is not visited before ; Add to first occurrence ; Mark it visited ; Stores values and positions ; Utility function to find minimum of pair type values ; Utility function to build segment tree ; Utility function to find LCA ; Function to return distance between two nodes n1 and n2 ; Maintain original Values ; Get First Occurrence of n1 ; Get First Occurrence of n2 ; Swap if low > high ; Get position of minimum value ; Extract value out of Euler tour ; return calculated distance ; Build Tree ; Store Levels ; Find L and H array ; Build segment Tree ; Driver function to test above functions ; Number of nodes ; Constructing tree given in the above figure ; Function to do all preprocessing
#include <bits/stdc++.h> NEW_LINE #define MAX  100001 NEW_LINE using namespace std ; struct Node { int data ; struct Node * left ; struct Node * right ; } ; struct Node * newNode ( int data ) { struct Node * temp = new struct Node ; temp -> data = data ; temp -> left = temp -> right = NULL ; return temp ; } int level [ MAX ] ; void FindLevels ( struct Node * root ) { if ( ! root ) return ; queue < pair < struct Node * , int > > q ; q . push ( { root , 0 } ) ; pair < struct Node * , int > p ; while ( ! q . empty ( ) ) { p = q . front ( ) ; q . pop ( ) ; level [ p . first -> data ] = p . second ; if ( p . first -> left ) q . push ( { p . first -> left , p . second + 1 } ) ; if ( p . first -> right ) q . push ( { p . first -> right , p . second + 1 } ) ; } } int Euler [ MAX ] ; int idx = 0 ; void eulerTree ( struct Node * root ) { Euler [ ++ idx ] = root -> data ; if ( root -> left ) { eulerTree ( root -> left ) ; Euler [ ++ idx ] = root -> data ; } if ( root -> right ) { eulerTree ( root -> right ) ; Euler [ ++ idx ] = root -> data ; } } int vis [ MAX ] ; int L [ MAX ] ; int H [ MAX ] ; void preprocessEuler ( int size ) { for ( int i = 1 ; i <= size ; i ++ ) { L [ i ] = level [ Euler [ i ] ] ; if ( vis [ Euler [ i ] ] == 0 ) { H [ Euler [ i ] ] = i ; vis [ Euler [ i ] ] = 1 ; } } } pair < int , int > seg [ 4 * MAX ] ; pair < int , int > min ( pair < int , int > a , pair < int , int > b ) { if ( a . first <= b . first ) return a ; else return b ; } pair < int , int > buildSegTree ( int low , int high , int pos ) { if ( low == high ) { seg [ pos ] . first = L [ low ] ; seg [ pos ] . second = low ; return seg [ pos ] ; } int mid = low + ( high - low ) / 2 ; buildSegTree ( low , mid , 2 * pos ) ; buildSegTree ( mid + 1 , high , 2 * pos + 1 ) ; seg [ pos ] = min ( seg [ 2 * pos ] , seg [ 2 * pos + 1 ] ) ; } pair < int , int > LCA ( int qlow , int qhigh , int low , int high , int pos ) { if ( qlow <= low && qhigh >= high ) return seg [ pos ] ; if ( qlow > high qhigh < low ) return { INT_MAX , 0 } ; int mid = low + ( high - low ) / 2 ; return min ( LCA ( qlow , qhigh , low , mid , 2 * pos ) , LCA ( qlow , qhigh , mid + 1 , high , 2 * pos + 1 ) ) ; } int findDistance ( int n1 , int n2 , int size ) { int prevn1 = n1 , prevn2 = n2 ; n1 = H [ n1 ] ; n2 = H [ n2 ] ; if ( n2 < n1 ) swap ( n1 , n2 ) ; int lca = LCA ( n1 , n2 , 1 , size , 1 ) . second ; lca = Euler [ lca ] ; return level [ prevn1 ] + level [ prevn2 ] - 2 * level [ lca ] ; } void preProcessing ( Node * root , int N ) { eulerTree ( root ) ; FindLevels ( root ) ; preprocessEuler ( 2 * N - 1 ) ; buildSegTree ( 1 , 2 * N - 1 , 1 ) ; } int main ( ) { int N = 8 ; Node * root = newNode ( 1 ) ; root -> left = newNode ( 2 ) ; root -> right = newNode ( 3 ) ; root -> left -> left = newNode ( 4 ) ; root -> left -> right = newNode ( 5 ) ; root -> right -> left = newNode ( 6 ) ; root -> right -> right = newNode ( 7 ) ; root -> right -> left -> right = newNode ( 8 ) ; preProcessing ( root , N ) ; cout << " Dist ( 4 , ▁ 5 ) ▁ = ▁ " << findDistance ( 4 , 5 , 2 * N - 1 ) << " STRNEWLINE " ; cout << " Dist ( 4 , ▁ 6 ) ▁ = ▁ " << findDistance ( 4 , 6 , 2 * N - 1 ) << " STRNEWLINE " ; cout << " Dist ( 3 , ▁ 4 ) ▁ = ▁ " << findDistance ( 3 , 4 , 2 * N - 1 ) << " STRNEWLINE " ; cout << " Dist ( 2 , ▁ 4 ) ▁ = ▁ " << findDistance ( 2 , 4 , 2 * N - 1 ) << " STRNEWLINE " ; cout << " Dist ( 8 , ▁ 5 ) ▁ = ▁ " << findDistance ( 8 , 5 , 2 * N - 1 ) << " STRNEWLINE " ; return 0 ; }