The first step I take when troubleshooting a problem is to know what I'm dealing with. In our case, we have a binary tree in which all nodes, not just the leaves, have real value (ie, not just indexing values). It was not provided by André if the tree is searchable or not, although in his code snippet he leaves it implicit. I will answer here for both cases.
Generalized binary tree
A tree is a structure that is given by the following rules:
A node is a constituent element of a tree,
A node has at most a single parent node,
A node may not have a parent, this case is called a root.
In addition, we have some concepts / conclusions derived from these definitions:
If A
, B
, and C
has as parent node X
, it is said that A
, B
and C
are children of X
,
A sheet is a node that has no children,
The simplest tree is composed only of the root,
A node, its children and all its descendants constitute a subtree,
two nodes belong to the same tree if they share the same root,
If I just navigate from any node to its child node, it will never happen that I find the same descendant node by two distinct paths.
A binary tree is a generalized tree specification; it has the same training rules and also the following:
For a tree to be binary, every node is limited to having at most 2 child nodes.
As an additional concept, we have child nodes identified by node left and node right .
To walk through a binary tree, I need to go through the root, the subtree on the left (the one formed by the node on the left) and the subtree on the right. The order in which I pass through each of these 3 elements roughly is indifferent.
So, if I make the visit in the node, left, right order, I have more or less this algorithm:
navega_arvore(nodo subarvore):
visita(subarvore)
se subarvore->esquerda != null:
navega_arvore(subarvore->esquerda)
se subarvore->direita != null:
navega_arvore(subarvore->direita)
This is the general structure of navigation. In case the node has a value indicated by inf
, and we want to get as much inf
as possible, we have this algorithm:
maior_inf_arvore(nodo subarvore):
inf_atual = subarvore->inf
maior_inf = inf_autal # até encontrar um filho com uma informação maior, o maior que eu tenho é o atual
se subarvore->esquerda != null:
inf_esquerda = maior_inf_arvore(subarvore->esquerda)
se inf_esquerda > maior_inf:
maior_inf = inf_esquerda
se subarvore->direita != null:
inf_direita = maior_inf_arvore(subarvore->direita)
se inf_direita > maior_inf:
maior_inf = inf_direita
retorne maior_inf
In recursion, I guarantee that I will go through all the descending nodes of the last node. I also guarantee that after this navigation, I will get as much information as possible within the subtree.
In C, that algorithm looks something like this:
int maior_inf_arvore(tipo_arvore *subarvore) {
int maior_inf, inf_atual, inf_esquerda, inf_direita;
inf_atual = subarvore->inf;
maior_inf = inf_autal; /* até encontrar um filho com uma informação maior, o maior que eu tenho é o atual */
if (subarvore->esquerda != null) {
inf_esquerda = maior_inf_arvore(subarvore->esq);
if (inf_esquerda > maior_inf) {
maior_inf = inf_esquerda;
}
}
if (subarvore->direita != null) {
inf_direita = maior_inf_arvore(subarvore->dir);
if (inf_direita > maior_inf) {
maior_inf = inf_direita;
}
}
return maior_inf;
}
Search binary tree
A binary search tree is a binary tree that has the following additional rules:
Every node has comparable information,
the child node on the left has less information than its parent,
The child node on the right has information greater than or equal to that of its parent.
So, on top of that definition, we do not have to navigate left. We also have the guarantee that if you have a child on the right, that child has more information, so I should not consider the information of the original. So, in pseudo-code, it would look like:
maior_inf_arvore_busca(nodo subarvore):
se subarvore->direita != null:
retorne maior_inf_arvore(subarvore->direita)
senão:
retorne subarvore->inf
In C:
int maior_inf_arvore_busca(tipo_arvore *subarvore) {
if (subarvore->dir != null) {
return maior_inf_arvore(subarvore->dir);
} else {
return subarvore->inf;
}
}
But this is a simple recursive strategy. It could be replaced by a simple iteration:
int maior_inf_arvore_busca(tipo_arvore *subarvore):
tipo_arvore *navegacao = subarvore
while (navegacao->dir != null) {
navegacao = navegacao->dir;
}
return navegacao-> inf;
}
NOTE
I did not do the root-of-tree treatment, but it's easy to do.