Escolar Documentos
Profissional Documentos
Cultura Documentos
Árvores
5 16
2 6 12 20
9 15 18 22
12 14
Fig. 1: Uma árvore binária ordenada.
• Cada elemento de uma árvore é chamado de nó (em inglês: node). A árvore da figura 1
possui um total de 13 nós.
• A ligação entre dois nós da árvore é chamada de ramo (em inglês: branch). Como toda
árvore é um grafo conexo sem ciclos, sabemos de antemão que a quantidade de ramos de
uma árvore é igual à sua quantidade de nós menos 1. Verifique que a árvore da figura 1
possui exatamente 12 ramos.
• Há uma hierarquia entre os elementos da árvore, de forma que para atingir um
determinado nó, é necessário passar antes por uma quantidade ≥ 0 de outros nós. Os nós
que precisamos visitar para chegar a um nó x são denominados ancestrais (em inglês:
ancestors) de x. Em contrapartida, dizemos que o nó x é um descendente (em inglês:
descendant) de cada um desses ancestrais. Dentre os ancestrais de um nó x dado, aquele
nó y que é mais próximo de x é chamado de pai de x. Na árvore da figura 1 o nó contendo
um 16 é o pai dos nós contendo os números 12 e 20. Os descendentes diretos de um nó
são seus filhos. Na árvore da figura 1 o nó contendo um 16 tem como filhos os nós cujos
valores são 12 e 20. Frequentemente chamamos os nós que possuem o mesmo pai de
irmãos.
• O grau de uma árvore é definido pela quantidade máxima de descendentes diretos que
um nó pode ter. Na árvore da figura 1 um nó pode ter no máximo 2 descendentes diretos,
então dizemos que ela possui grau 2 ou, então, que é uma árvore binária (em inglês:
binary tree).
• Dizemos que o nó que possui grau 0, ou seja, que não possui descendentes, é uma folha
(em inglês: leaf) da árvore. Na árvore do exemplo temos 6 folhas (os nós com os valores
2, 6, 12, 14, 18 e 22). Um nó que possui pelo menos um descendente costuma ser
chamado de nó interno (em inglês: internal node) da árvore, e a árvore da figura 1 possui
7 nós internos (os nós com os valores 8, 5, 16, 12, 20, 9 e 15).
Aplicações
Árvores são adequadas para representar hierarquias, como por exemplo, a ordem de execução
das operações requeridas por uma expressão aritmética, ou a cadeia de subordinação de
conceitos (um organograma ou auto-relacionamento), ou ainda para representar eficientemente
valores que precisam ser pesquisados com freqüência. A figura 2 mostra dois exemplos clássicos
do uso de árvores: a representação de expressões aritméticas e uma hierarquia. Para ambos é
mostrado o conceito original e a árvore correspondente.
P
a b
E S
C
A F
B C Y P
E S
#include <stdio.h>
struct regNo
{ struct regNo *esq;
int valor;
struct regNo *dir;
};
typedef struct regNo TNo;
int main()
{ TNo *raiz = NULL, *aux, *pai;
int numero;
while(1)
{ printf("\nInforme o valor:\n"); scanf("%d", &numero);
aux->valor = numero;
aux->dir = NULL;
aux->esq = NULL;
if( r == NULL )
return NULL;
else
{ c = r;
while(1)
{ if( n <= c->valor )
/* n é descendente do lado esquerdo de c */
if( c->esq == NULL )
return c;
else
c = c->esq;
else
/* n é descendente do lado direito de c */
if( c->dir == NULL )
return c;
else
c = c->dir;
}
}
}
Fig. 6: Implementação não-recursiva da rotina AchaPai.
Após a inclusão dos elementos na árvore, o programa imprime quantos nós existem na árvore e,
em seguida, os valores nela contidos. Para determinar quantos elementos existem na árvore é
utilizada a função ContaNos, que recebe como parâmetro o endereço de um nó da árvore e
retorna um inteiro com o valor da contagem, como mostra o código apresentado na figura 7. A
abordagem adotada nessa rotina é, recursivamente, somar 1 referente ao nó raiz da árvore mais a
if( r != NULL )
{ for( c=0; c<n; c++) printf("\t");
printf("%d\n", r->valor);
ImprimeArvore(r->esq, n+1);
ImprimeArvore(r->dir, n+1);
}
}
Fig. 9: Implementação recursiva da rotina ImprimeArvore.
TPilha pilha[1000];
TNo *noh;
int d, topo = 0;
noh = r;
while(noh != NULL || topo > 0)
{ if(noh != NULL)
{ for( d=0; d<n; d++) printf(" ");
printf("%d\n", noh->valor);
pilha[topo].ender = noh;
pilha[topo].nivel = n;
topo++;
noh = noh->esq;
n++;
}
else
{ topo--;
noh = pilha[topo].ender;
n = pilha[topo].nivel;
noh = noh->dir;
n++;
}
}
}