The general recursive algorithm relies on the fact that the height of a binary tree is the greater of height of its left and right sub-trees plus 1.
The height of the empty tree is 0.
That's a very basic kind of recursion. The trivial case is 0 and more complex cases rely on working out the same thing for sub-parts of the problem and combining them except in the trivial case!
It's a bit like saying the height of a brick wall is the height of the wall with one brick taken off plus one, with the height of no wall being 0.
OK, that's a mad way to measure walls but it's not uncommon in computing!
BinTree
will be a pointer. So the line if(BT)
will be false if BT
is NULL
(the empty tree) and the function returns a height of zero (jumping straight to else return 0
).
NB: return 0;
would do here. There's no need for an else
because both sides of the if-statement return.
So now you look at the detail of the if-true branch.
HL = PostOrderGetHeight(BT->Left);
HR = PostOrderGetHeight(BT->Right);
MaxH = (HL>HR)?HL:HR;
return (MaxH+1);
HL
(meaning height left) is the height of the left side of the tree from the node, HR
is the height of the right side.
MaxH = (HL>HR)?HL:HR
uses the ternary operator (inline if expression) that says if HL>HR
the value of this expression is HL
otherwise HR
.
That gives us our maximum height of the left and right sub-trees.
The return statement (return (MaxH+1);
) adds the 1.
As stated in a comment it would be preferable to omit:
int HL,HR, MaxH;
And write
int HL = PostOrderGetHeight(BT->Left);
int HR = PostOrderGetHeight(BT->Right);
int MaxH = (HL>HR)?HL:HR;
Before C99 (the 1999 standard) you were required to declare all variables at the start of the function. That gave the compiler an easy ride determine how much stack was required.
But it should not be preferred style unless shackled to a compiler that imposes the rule (not even all 20th century compilers did).
It's less readable and reduce safety by risking the use of uninitialized data such as in blocks it's not used in.
Slightly more obscurely it could also stop the compiler seeing opportunities to optimize the stack layout.
But in short I wonder if this code was written for a old-school compiler or by an old-timer. I don't apologise to calling anyone an old-timer. I wrote C code on those compilers. It's not an insult.
The definition of BinTree
isn't provided but it must be similar to:
typedef struct BinTree_tag;
typedef struct {
struct BinTree_tag *Left;
struct BinTree_tag *Right;
} *BinTree ;