You can find l()
for the entire tree in less than O(n^2) time. The idea is to traverse the tree in order, maintaing a stack of the nodes you've visited while traversing the left branch. When you get to a leaf, that is the leftmost node for the entire branch.
Here's an example:
class BTreeNode
{
public readonly int Value;
public BTreeNode LeftChild { get; private set; }
public BTreeNode RightChild { get; private set; }
}
void ShowLeftmost(BTreeNode node, Stack<int> stack)
{
if (node.LeftChild == null)
{
// this is the leftmost node of every node on the stack
while (stack.Count > 0)
{
var v = stack.Pop();
Console.WriteLine("Leftmost node of {0} is {1}", v, node.Value);
}
}
else
{
// push this value onto the stack so that
// we can add its leftmost node when we find it.
stack.Push(node.Value);
ShowLeftmost(node.LeftChild, stack);
}
if (node.RightChild != null)
ShowLeftmost(node.RightChild, stack);
}
The complexity is clearly not O(n^2). Rather, it's O(n).
It takes O(n) to traverse the tree. No node is placed on the stack more than once. The worst case for this algorithm is a tree that contains all left nodes. In that case it's O(n) to traverse the tree and O(n) to enumerate the stack. The best case is a tree that contains all right nodes, in which case there is never any stack to enumerate.
So O(n) time complexity, with O(n) worst case extra space for the stack.