UNIP – Ciência da Computação
---------------------------------------------------------------------------------------------------------Lógica de Programação
Programação
ÁRVORES
Uma árvore é uma estrutura de dados bidimensional, não linear, que possui
propriedades espaciais e admite muitas operações de conjuntos dinâmicos,
tais como: consulta, inserção, remoção, entre outros. É diferente das listas e
pilhas, uma vez que estas são estruturas de dados lineares.
Uma árvore, de modo geral, possui as seguintes características:
nó raiz: nó do topo da árvore, do qual descendem os demais nós. É o
primeiro nó da árvore;
nó interior: nó do interior da árvore (que possui descendentes);
nó terminal: nó que não possui descendentes;
trajetória: número de nós que devem ser percorridos até o nó
determinado;
grau do nó: número de nós descendentes do nó, ou seja, o número de
subárvores de um nó;
grau da árvore: número máximo de subárvores de um nó;
altura da árvore: número máximo de níveis dos seus nós;
altura do nó: número máximo de níveis dos seus nós;
Para exemplificar a explicação sobre as características de uma árvore,
vamos fazer uma análise da árvore apresentada na figura 1:
a
b
d
c
f
e
i
g
h
j
k
|Figura 1| Árvores
o nó a é determinado nó raiz, tem grau dois pois possui dois filhos, os nós
b e c, que também podem ser chamados de subárvores ou nós
descendentes;
o nó b tem grau três pois possui três filhos : os nós d, e e f; o nó b também
é denominado pai dos nós d, e e f;
----------------------------------------------------------------------------------------------------Prof. Marcelo Nogueira
1
UNIP – Ciência da Computação
---------------------------------------------------------------------------------------------------------Lógica de Programação
Programação
os nós d e e são nós terminais, isto é, não possuem descendentes e por
isso têm grau zero;
o nó f tem grau dois e tem como filhos os nós i e j;
o nó i é um nó terminal e possui grau zero;
o nó j tem grau um e é pai do nó k, que é terminal;
o nó c tem grau dois e é pai dos nós g e h, que são nós terminais;
a árvore possui grau três, pois este é o número máximo de nós
descendentes de um único pai;
a árvore tem altura igual a 5, já o nó b tem altura igual a 4, o nó c tem
altura igual a 2, o nó k tem altura igual a 1 e assim por diante;
para definirmos a trajetória a ser percorrida vamos supor que se deseje
chegar ao nó j, então o caminho a ser percorrido será a, b, f, j, conforme
ilustrado na figura 2.
a
b
d
c
f
e
i
g
h
j
k
|Figura 2| Trajetória
As árvores podem ser do tipo listas generalizadas ou binárias. As árvores do
tipo listas generalizadas possuem nós com grau maior ou igual a zero,
enquanto uma árvore do tipo binária sempre possui nós com grau menor ou
igual a 2. Veja os exemplos de árvores apresentados na Figura 3.
ÁRVORES BINÁRIAS
Conforme já dissemos anteriormente, uma árvore binária sempre possui nós
com grau menor ou igual a dois, isto é, nenhum nó possui mais do que dois
descendentes
----------------------------------------------------------------------------------------------------Prof. Marcelo Nogueira
2
UNIP – Ciência da Computação
---------------------------------------------------------------------------------------------------------Lógica de Programação
Programação
Árvore como lista generalizada
Árvore binária
a
b
e
a
c
f
d
g
h
b
i
c
d
f
e
j
h
g
i
j
|Figura 3| Árvores
57
45
77
60
13
9
25
5
55
84
78
95
|Figura 4| Árvore Binária
diretos (dois filhos). Nesse tipo de árvore também existe uma
particularidade quanto à posição dos nós: os nós da direita sempre possuem
valor superior ao do nó pai, e os nós da esquerda sempre possuem valor
inferior ao do nó pai.
O algoritmo a seguir apresenta as variáveis que serão utilizadas para a
manipulação da árvore – note que existe grande similaridade com os nós
criados para manipulação das listas. O algoritmo tem a definição de um
----------------------------------------------------------------------------------------------------Prof. Marcelo Nogueira
3
UNIP – Ciência da Computação
---------------------------------------------------------------------------------------------------------Lógica de Programação
Programação
registro que possui as variáveis valor, esq e dir, a variável apontador, que
será utilizada para fazer a referência a nós localizados à direita e a esquerda
(da raiz ou do nó pai), e a variável raiz, que guardará o valor do nó raiz da
árvore.
EXEMPLO 1: PSEUDOCÓDIGO QUE REPRESENTA UMA ÁRVORE BINÁRIA.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
algoritmo BArvore
aaatipo apontador: ^no_arvore
aaatipo no_arvore: registro
aaaaaaaaaaaaaaaaaaavalor: inteiro
aaaaaaaaaaaaaaaaaaaesq: apontador
aaaaaaaaaaaaaaaaaadir: apontador
aaatipo no_arvore: fim
aaavar
aaavarraiz: apontador
Função inserir (arvore: no_arvore, novoNo: inteiro): no_arvore
aaavar
aaavarapoio: no_arvore
aaainicio
aaavarSe (arvore = nulo) então
aaavarSe apoio.valor ← novoNo
aaavarSe retorne (apoio)
aaavarSenão
aaavarSe Se (novoNo < arvore.valor) então
aaavarSe Se arvore^.esq ← inserir(arvore^.esq, novoNo)
aaavarSe Senão
aaavarSe Se arvore^.dir ← inserir(arvore^.dir, novoNo)
aaavarSe Fim-se
aaavarFim-se
aaavarretorne (arvore)
aaaFim
Procedimento inserirNo (novoValor: inteiro)
aaainicio
aaavarraiz ← inserir (raiz,novoValor)
aaafim
Procedimento exibir_esquerdo
aaaarv: no_arvore
aaainicio
aaainiarv ← raiz
aaainiSe (arv <> nulo) então
aaainiSe (mostre(arv ^.valor)
exibir_esquerdo(arv ^.esq)
aaainifim
Procedimento exibir_direito
aa arv: no_arvore
aa inicio
aa iniarv ← raiz
aa iniinicio
aa iniiniSe (arv <> nulo) então
aa iniiniSe (mostre (arv^.valor)
exibir_direito (arv^.dir)
aa iniinifim
u
----------------------------------------------------------------------------------------------------Prof. Marcelo Nogueira
4
UNIP – Ciência da Computação
---------------------------------------------------------------------------------------------------------Lógica de Programação
Programação
51.
52.
53.
54.
Procedimento exibir_raiz( )
aaainicio
aaainimostre (“Raiz”, raiz)
aaafim
Os comentários serão feitos juntamente com os comentários do programa.
EXEMPLO 2: PSEUDOCÓDIGO
PARA
REPRESENTAR
O
PROCEDIMENTO
DA
EXCLUSÃO DE NÓS COM ÁRVORES BINÁRIAS.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
Procedimento excluirNo (item: inteiro)
var
aaatempNo: no_arvore
aaapai: no_arvore
aaafilho: no_arvore
aaatemp: no_arvore
inicio
aaatempNo ← raiz
aaapai ← nulo
aaafilho ← raiz
aaaEnquanto (tempNo < > nulo .e. tempNo^.valor < > item) faça
aaaEnqpai ← tempNo
aaaEnqSe(item < tempNo^.valor) então
aaaEnqSe(tempNo ← tempNo^.esq
aaaEnqSenão
aaaEnqSeatempNo ← tempNo^.dir
aaaEnqFim-se
aaaEnqSe (tempNo = nulo) então
aaaEnqSe (Mostre (“item não localizado”)
aaaEnqFim-se
aaaEnqSe (pai = nulo) então
aaaEnqSe (Se (tempNo^.dir = nulo)
aaaEnqSe (Se (raiz ← tempNo^.esq
aaaEnqSe (Fim-se
aaaEnqSe (Se (tempNo.esq = nulo)
aaaEnqSe (Se (raiz ← tempNo^.dir
aaaEnqSe (Fim-se
aaaEnqSenão
aaaEnqSe (temp ← tempNo
aaaEnqSe (filho ← tempNo^.esq
aaaEnqSe (Enquanto (filho.dir < > nulo) faça
aaaEnqSe (Enqtemp ← filho
aaaEnqSe (Enq filho ← filho^.dir
aaaEnqSe (Fim-enquanto
aaaEnqSe (Se (filho < > tempNo^.esq) então
aaaEnqSe (Se temp^.dir ← filho.^esq
aaaEnqSe (Se temp.^esq ← raiz.^esq
aaaEnqSe (Fim-se
aaaEnqSe (filho.^dir ← raiz.^dir
aaaEnqSe (raiz ← filho
aaaEnqFim-se
aaaEnqSe (tempNo.^dir = nulo) então
aaaEnqSe Se (pai.^esq = tempNo.^esq
aaaEnqSe Se (pai.^esq ← tempNo.^esq
aaaEnqSe Senão
aaaEnqSe Se (pai.^dir ← tempNo.^esq
aaaEnqSe Fim-se
----------------------------------------------------------------------------------------------------Prof. Marcelo Nogueira
5
UNIP – Ciência da Computação
---------------------------------------------------------------------------------------------------------Lógica de Programação
Programação
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
aaaEnqSenão
aaaEnqSe Se (tempNo^.esq = tempNo) então
aaaEnqSe Se Se (pai.^esq = tempNo) então
aaaEnqSe Se Se (pai^.esq ← tempNo^.dir
aaaEnqSe Se Senão
aaaEnqSe Se Se (pai^.dir ← tempNo^.dir
aaaEnqSe Se fim-se
aaaEnqSe Senão
aaaEnqSe Se (temp ← tempNo
aaaEnqSe Se (filho ← tempNo^.esq
aaaEnqSe Se (Enquanto (filho.dir < > nulo) faça
aaaEnqSe Se (Enqtemp ← filho
aaaEnqSe Se (Enqfilho ← filho^.dir
aaaEnqSe Se (Fim-enquanto
aaaEnqSe Se (Se (filho < > tempNo.esq) então
aaaEnqSe Se (Enqtemp.^dir ← filho.esq
aaaEnqSe Se (Enqfilho.^esq ← tempNo.esq
aaaEnqSe Se (Fim-se
aaaaaaaaaaaafilho.^dir ← tempNo.^dir
aaaaaaaaaaaaSe (pai^.esq = tempNo) então
aaaaaaaaaaaaSe (pai.^esq ← filho
aaaaaaaaaaaaSenão
aaaaaaaaaaaaSe (pai.^dir ← filho
aaaaaaaaaaaafim-se
aaaEnqSe Senão
fim
----------------------------------------------------------------------------------------------------Prof. Marcelo Nogueira
6
Download

ÁRVORES - Professor Marcelo Nogueira