简体   繁体   中英

Calculating the vertical sum in binary tree

This is a code i came across which calculates the vertical sum in binary tree. As the code doesn't have any documentation at all ,i am unable to understand how does it actually works and what exactly the condition if(base==hd) does? Help needed :)

 void vertical_line(int base,int hd,struct node * node)
{
    if(!node) return;
    vertical_line(base-1,hd,node->left);
    if(base==hd) cout<<node->data<<" ";    
    vertical_line(base+1,hd,node->right);
}
void vertical_sum(struct node * node)
{
    int l=0,r=0;
    struct node * temp=node;
    while(temp->left){
        --l;temp=temp->left;
    }
    temp=node;
    while(temp->right){
    ++r;temp=temp->right;
    }
    for(int i=l;i<=r;i++)
    {
        cout<<endl<<"VERTICAL LINE "<<i-l+1<<" : ";
        vertical_line(0,i,node);
    }
}

It is trying to display the tree in vertical order - let's try to understand what is vertical order

Take the example of following tree

                  4
            2           6
         1     3     5     7

Following is the distribution of nodes across vertical lines

Vertical Line 1 - 1
Vertical Line 2 - 2
Vertical Line 3 - 3,4,5
Vertical Line 4 - 6
Vertical Line 5 - 7

How did we decide that 3,4,5 are part of vertical line 3. We need to find horizontal distance of nodes from root to decide if they belong to same line or not. We start with root which has horizontal distance of zero. If we move left then we need to decrement the distance of parent by 1 and if we move to right we need to increment the distance of parent by 1. Same applies to every node in the tree ie if parent has horizontal distance of d, then it's left child's distance is d-1 and right child's distance is d+1

In this case node 4 has distance 0. Node 2 is left child of 4, so it's distance is -1 (decrement by 1). Node 6 is right child of 4, so it's distance is 1 (increment by 1).

Node 2 has distance -1. Node 3 is right child of 2, so it's distance is 0 (increment by 1) Similarly for Node 5. Nodes 3,4,5 have horizontal distance of zero so they fall on the same vertical line

Now coming to your code

while(temp->left){
        --l;temp=temp->left;
    }

In this loop, you are computing distance of farthest node from root on left hand side (This doesn't work all the time, we will discuss that later). Every time you move left, you are decrementing value of l by 1.

while(temp->right){
    ++r;temp=temp->right;
    }

With logic similar to above, you are distance of computing farthest node from root on right hand side

Now you know the farthest distances on left hand and right hand sides, you are displaying the nodes vertically

 for(int i=l;i<=r;i++)
    {
        cout<<endl<<"VERTICAL LINE "<<i-l+1<<" : ";
        vertical_line(0,i,node);
    }

Every iteration in above loop will display the nodes on vertical line. (This is not efficient). You are calling vertical_line method for every line

void vertical_line(int base,int hd,struct node * node)
{
    if(!node) return;
    vertical_line(base-1,hd,node->left);
    if(base==hd) cout<<node->data<<" ";    
    vertical_line(base+1,hd,node->right);
}

Above method will print the nodes falling on the line hd. This method iterates over entire tree, computing the distance for every node ie base contains the value of horizontal distance of a node. If a node is part of vertical line hd, then base becomes equal to hd ie base = hd which is when your code is printing the value of the node

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM