O que é uma árvore

16 

Full text

(1)

Estrutura de Dados

Tema 6: Árvores

binárias.

Segundo Knuth (1973), uma árvore pode ser formalmente definida como sendo um conjunto finito T de um ou mais nós, onde:

a) existe um nó especialmente designado para ser a raiz de T; e

b) os demais nós são parti- cionados dentro de m≥0 conjuntos disjuntos T1,T2,

..., Tm e cada um destes

conjuntos torna-se uma árvore, chamada sub-árvores da raiz.

O que é uma árvore

Características de uma árvore

raiz:- o nó inicial da árvore;

Grau: o número de filhos que um nó possui;

Nível (ou profundidade): a distância de um nó até a raiz;

Altura: o maior nível encontrado na árvore (altura de uma árvore com n nós pode variar de lg(n) até n-1;

(2)

6

9 14

25

folha Este nó está no nível 2 e possui grau 0. Este nó está no nível

1 e possui grau 1.

Este nó está no nível 0 e possui grau 2. raiz

folha

Este nó está no nível 1 e possui grau 0.

Altura da árvore é 2

O que não é uma árvore

A

B C

D G

D C

A B

O que é uma árvore binária

Um conjunto de finito de elementos que pode estar vazio ou particionado em 3 subconjuntos disjuntos.

A

B C

(3)

Árvore binária

• Em uma árvore binária os nós podem assumir grau 0, 1 ou 2;

• Em uma árvore binária completa, todos os nós possuem grau igual a 2;

• O número máximo de elementos em uma árvore de altura n é 2n.

Árvore binária de busca

Uma árvore binária de busca possui elementos menores que a raiz armazenados na sub-árvore da esquerda e elementos maiores que a raiz na sub-árvores da direita.

25

38 12

19

Árvore binária como um TDA

Características:

• Conjunto de elementos;

(4)

Árvore binária de busca como um TDA

Operações:

• Inserir novo elemento • Buscar um elemento • Mostrar todos os

elementos

• Remover um elemento • Contar elementos • Calcular nível de um elemento

Inserção de elementos em uma

árvore binária de busca

• O primeiro elemento inserido assumirá o papel

de raiz da árvore;

• Todo novo elemento entrará na árvore como

uma folha;

• Se o elemento for menor

ou igual à raiz será in- serido no ramo da esquer- da. Caso contrário, no ramo da direita (para árvores decrescentes inverte-se a a regra).

Análise gráfica de inserções em uma

árvore binária

(5)

Continuando

Tema 6: Árvores binárias.

Remoção de elementos em uma árvore

binária de busca

Podem ocorrer as seguintes situações:

1. Elemento a ser removida é uma folha (sem

filhos à esquerda e à direita);

2. Elemento a ser removido possui apenas um filho (à direita ou à esquerda); 3. Elemento a ser removido

possui dois filhos.

Remoção na situação 1

Remover os elementos 19 e 38

25

38 12

19

25

(6)

Remoção na situação 2 – filho à

esquerda

Remover os elementos 12 e 65

29

65 12

34 58 5 49

29

5

34 58 49

Remoção na situação 2 – filho à

direita

Remover os elementos 19 e 87

58

87 19

24 41 94 37

58

94

24 41 37

Remoção na situação 3 – filhos à

esquerda e à direita

Remover o elemento 23 e 67- estratégia 1

58

60

28 54 45 4

2 15 94

58

67 23

28 54 45 4

2 15

(7)

Remoção na situação 3 – filhos à

esquerda e à direita

Remover o elemento 23 e 67 -estratégia 2

58

94

28 54 45

4

2 15

60 58

67 23

28 54 45 4

2 15

60 94

Percurso em uma árvore binária

1. Pré-ordem: raiz, árvore esquerda, sub-árvore direita

2. Em ordem: árvore esquerda, raiz, sub-árvore direita

3. Pós-ordem: sub-árvore esquerda, sub-árvore direita, raiz

Exemplo de percurso pré-ordem

Pré-ordem: H, F, C, D, Q, L, J, N, U

H

Q F

J C

D

L U

(8)

Exemplos de percurso em ordem

Em ordem: C, D, F, H, J, L, N, Q, U

H

Q F

J C

D

L U

N

Exemplos de percurso pós-ordem

Pós-ordem: D, C, F, J, N, L, U, Q, H

H

Q F

J C

D

L U

N

(9)

Implementar em C funções que utilizem uma árvore binária de busca para:

• inserir elementos • remover elementos

• percorrer a árvore:pré-ordem • percorrer a árvore: em

ordem

• percorrer a árvore: pós-ordem

#include <stdio.h> #include <stdlib.h>

struct arvoreBinaria { int elem;

arvoreBinaria *dir, *esq; };

int main() {

arvoreBinaria *raiz, *p; int x; char op; raiz = NULL;

do { fflush(stdin);

printf("\n1- Inserir\n2- Excluir \n3-preOrdem \n4- emOrdem\n5- posOrdem \n6- Sair "); scanf("%c", &op);

switch (op) { case '1':

(10)

case '2':

if (raiz != NULL) {

printf("\nDigite um valor "); scanf("%d", &x);

raiz=remove(raiz,x); }

else printf("\nArvore vazia.\n");

break;

case ‘ 3': preOrdem(raiz); break;

case '4':

emOrdem(raiz); break;

case ‘5':

posOrdem(raiz); } // fim switch }while (op!=‘ 6'); }

arvoreBinaria *insere(arvoreBinaria *a, int el) {

if (a == NULL) {

a = new (arvoreBinaria); a->elem = el;

(11)

else { if (el <= a->elem)

a->esq=insere(a->esq, el); else a->dir=insere(a->dir, el); } return a;

}

arvoreBinaria *remove(arvoreBinaria *a, int el) {

arvoreBinaria *p, *p2;

if (a->elem == el) {

if (a->esq == a->dir) { // remoção de folha

delete(a); return NULL; }

else if (a->esq == NULL) { //filho a direita p=a->dir;

delete(a); return p; }

else if (a->dir == NULL) { //filho a esq

p=a->esq; delete(a); return p; }

else { //tem 2 filhos p2= a->dir; p= a->dir;

while (p->esq) p=p->esq; p->esq = a->esq; delete(a); return p2; }

(12)

if (a->elem < el) {

if (a->dir!=NULL) a->dir = remove(a->dir, el); else printf(“Elemento nao encontrado."); }

else { if (a->esq!=NULL)

a->esq = remove(a->esq, el); else printf(“Elemento

não encontrado"); }

return a; }

void preOrdem(arvoreBinaria *a) { if (a != NULL)

{ printf("\n%d ", a->elem); preOrdem(a->esq); preOrdem(a->dir); }

}

void emOrdem(arvoreBinaria *a) { if (a != NULL)

{ emOrdem(a->esq); printf("\n%d ", a->elem); emOrdem(a->dir); }

(13)

void posOrdem(arvoreBinaria *a) { if (a != NULL)

{ posOrdem(a->esq); posOrdem(a->dir);

printf("\n%d ", a->elem); }

}

Finalizando

Tema 6: Árvores binárias.

Árvore AVL

Quando os ramos (sub-árvores) ficarem com alturas muito diferentes, as árvores passam a ficar semelhantes às estruturas lineares (listas,

filas e pilhas), nas quais o processo de busca é menos eficiente.

(14)

Árvore AVL (

Adelson- Velsky e Landis)

Uma árvore AVL é uma árvore binária onde as alturas das duas sub-árvores de qualquer nó nunca ultrapassa 1.

O balanceamento de um nó é definido como a altura de sua sub-árvore

esquerda menos a altura de sua sub-árvore direita.

| alt_esq – alt_dir | ≤ 1

Como garantir o balanceamento?

Após uma inserção ou remoção, deve-se promover ajustes na árvores, de tal forma que: a) A árvore continue sendo uma árvore binária

de busca (a ordenação dos elementos seja mantida);

b) O módulo da diferença entre as alturas das sub-árvores esquerda e direita de qualquer nó seja inferior a 1.

Como garantir o balanceamento?

Os ajustes são chamados Rotações (à direita ou à esquerda).

Seja N o nó desbalanceado, poderá ser preciso: a) Rotação Simples – rotaciona-se apenas N b) Rotação Dupla – primeiro

(15)

Rotação simples para direita

A inserção de A provoca desbalanceamento em F.

H

Q F

J C

A

L U

N

H

Q C

J

A F L U

N

Rotação simples para direita

A inserção de 15 provoca desbalanceamento em 30.

30

90 20

10

15 28

20

30 10

15 28 90

Rotação simples para esquerda

A inserção de G provoca desbalanceamento em C.

J

Q F

G L U

N C

J

Q C

G

F L U

(16)

Rotação simples para esquerda

A inserção de R provoca desbalanceamento em J.

Q

U J

L R

C J

Q C

L U

R

Rotação dupla (direita - esquerda)

A inserção de 19 provoca desbalanceamento em 32. 37 59 14 8 19 26 1ª 2ª 37 59 26 14 19 2ª 8 26 37 14

8 19 59

Rotação dupla (esquerda - direita)

A inserção de 40 provoca desbalanceamento em 35.

35

21 68

Figure

Updating...

References

Updating...

Related subjects :