I have been doing some programming 'exercises'. I'm trying to come up with the most efficient algorithm for tree traversal.
Consider the following function signature:
CNode * CNode::find(int number) const
where CNode
structure is not organized as a binary search tree (otherwise obviously a faster algorithm would have been used - not involving the entire tree traversal), so all the nodes have to be inspected.
I have implemented 3 algorithms so far:
Stack-based search
CNode * CNode::findStackBased(int number)
{
Node *tmp = this;
stack<CNode*> onStack;
while (tmp != NULL || !onStack.empty())
{
if (tmp == NULL)
{
tmp = onStack.top();
onStack.pop();
}
if (tmp->number == number)
{
return tmp;
}
if (tmp->right)
{
onStack.push(tmp->right);
}
tmp = tmp->left;
}
return NULL;
}
Recursive search
CNode * CNode::findRecursion(int number)
{
if (this->number == number)
{
return this;
}
Node * result = NULL;
if (this->left != NULL && (result = left->findRecursion(data)))
{
return result;
}
if (this->right != NULL)
{
return this->right->findRecursion(data);
}
return NULL;
}
Walking along the edge
CNode * CNode::findWalkAlongTheEdge(int number)
{
Node *tmp = this;
while (tmp != NULL)
{
if (tmp->number == number)
{
return tmp;
}
if (tmp->left != NULL)
{
tmp = tmp->left;
continue;
}
else if (tmp->right != NULL)
{
tmp = tmp->right;
continue;
}
else
{
while (1)
{
if (tmp->parent->left == tmp)
{
if (tmp->parent->right != NULL)
{
tmp = tmp->parent->right;
break;
}
}
else
{
if (tmp->parent == this)
{
return NULL;
}
tmp = tmp->parent;
}
}
}
}
return NULL;
}
Each of the above have have some advantages/drawbacks, but performance wise 'walking along the edge is the winner so far(out of the 3 given above).
My question is:
Do you see any way to optimize it further (recursive implementation already benefits from the tail recursion optimization, at least gcc
seems to optimize it this way)?