Reputation: 1354
Here's a code snippet of a solution that calculates height of each node in a binary tree and stores the height in each node. The code traverse the tree recursively, and below is the Node
constructor.
class Node {
public:
int height; // to be set by computeHeight()
Node *left, *right;
Node() { height = -1; left = right = nullptr; }
~Node() {
delete left;
left = nullptr;
delete right;
right = nullptr;
}
};
Below is the function which computes and stores height at each Node
. Where I am confused is how do leftHeight
and rightHeight
get updated by n->left->height
and n->right->height
if at construction, height
is set to -1
?
void computeHeight(Node *n) {
if (n == nullptr) {
return;
}
computeHeight(n->left);
computeHeight(n->right);
int leftHeight = -1;
int rightHeight = -1;
if (n->left != nullptr) {
leftHeight = n->left->height;
}
if (n->right != nullptr) {
rightHeight = n->right->height;
}
n->height = std::max(leftHeight, rightHeight) + 1;
}
Here is the main file that runs the function computeHeight
int main() {
Node *n = new Node();
n->left = new Node();
n->right = new Node();
n->right->left = new Node();
n->right->right = new Node();
n->right->right->right = new Node();
n->right->right->right->left = new Node();
computeHeight(n);
delete n;
n = nullptr;
return 0;
}
Upvotes: 0
Views: 809
Reputation: 279
We can solve this problem with a basic case of induction. Basically, let's start with the base case, and then assuming any case n
works, we have to check if case n+1
works. In the case of calculating the heights of the nodes in a Binary Tree, the base case is when the root node is a leaf node, and for the n+1
case the left/right side nodes are the n
cases. You can think of it as n is the height of the current node, and n=0
is the leaf node base case.
When the root node is a leaf, both the left and right side nodes are nullptr
the method essentially turns into
void computeHeight(Node *n) {
int leftHeight = -1;
int rightHeight = -1;
n->height = std::max(leftHeight, rightHeight) + 1;
}
in which case n->height
becomes 0
, which is correct for a leaf node. Now, when the node is a non-leaf node, the statements
computeHeight(n->left);
computeHeight(n->right);
are already called before the calculation. This essentially makes it so that we assume that both the left and right side nodes are already taken care of, and their heights are correct. Then, we can use the left and right nodes' heights to calculate the root node's height, which is calculated through
int leftHeight = -1;
int rightHeight = -1;
if (n->left != nullptr) {
leftHeight = n->left->height;
}
if (n->right != nullptr) {
rightHeight = n->right->height;
}
n->height = std::max(leftHeight, rightHeight) + 1;
The trick here is that we already have called computeHeight()
on the left and right side nodes so that when we do the calculations on the current node, we can safely assume that the child nodes have been totally taken care of. Also, the child nodes are calculated before the root node, so the program will first trickle all the way down to the leaves before coming back up and calculating the non-leaf nodes.
Upvotes: 1
Reputation: 87959
Imagine a leaf node (left and right are nullptr). Then n->left != nullptr
and n->right != nullptr
are false so the calculation effectively becomes
int leftHeight = -1;
int rightHeight = -1;
n->height = std::max(leftHeight, rightHeight) + 1;
which is effectively
n->height = 0;
Now because of the way the recursion is done, each node gets it height calculated after it's children have had their heights calculated. So imagine a node with two children, each of which is a leaf node. We've already seen that leaf nodes get a height of zero. So the calculation for such a node is effectively
int leftHeight = -1;
int rightHeight = -1;
if (n->left != nullptr) {
leftHeight = 0; // because n->left is a leaf node
}
if (n->right != nullptr) {
rightHeight = 0; // because n->right is a leaf node
}
n->height = std::max(leftHeight, rightHeight) + 1;
which means that you end up with n->height = 1
for that node.
And so on. These calculations perculate up the tree, starting at the leaves, until finally the root gets it's height set.
Upvotes: 2