Reputation: 605
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);
}
}
Upvotes: 1
Views: 691
Reputation: 173
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 i.e 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 i.e 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 i.e base = hd which is when your code is printing the value of the node
Upvotes: 1