Anda di halaman 1dari 21

CEETEPS CENTRO ESTADUAL DE EDUCAO TCNICA PAULA SOUZA FACULDADE DE TECNOLOGIA ANLISE E DESENVOLVIMENTO DE SISTEMAS

MURILO APARECIDO PANOSSO

RVORE BINRIA RVORE AVL

Taquaritinga - SP 2011

Sumrio
CEETEPS CENTRO ESTADUAL DE EDUCAO TCNICA PAULA SOUZA........1 FACULDADE DE TECNOLOGIA.........................................................................1 Sumrio.......................................................................................................... 2 Arvore Binaria................................................................................................ 3 Alguns tipos de rvore................................................................................4 Arvore Binaria AVL.........................................................................................8 Exemplo de cdigo para rvores Binrias AVL:...........................................9 Construo da rvore Binria.......................................................................17 Concluso.....................................................................................................19 Referncias..................................................................................................21

Arvore Binaria
Uma rvore binria (chamada de binria pois de cada n podem nascer at 2 novos ns) uma estrutura de dados caracterizada por: - Ou tem um elemento distinto, denominado raiz, com dois ponteiros para duas estruturas diferentes, denominadas sub-rvore esquerda e sub-rvore direita.

Exemplificao de uma Arvore Binria

Perceba que a definio recursiva e, devido a isso, muitas operaes sobre rvores binrias utilizam recurso. o tipo de rvore mais utilizado na computao. A principal utilizao de rvores binrias so as rvores de busca binria. Uma definio mais concreta Uma rvore binria (= binary tree) formada de ns; cada n tem um certo contedo (por exemplo, um nmero inteiro) e os endereos (das razes) de duas subrvores: uma esquerda e uma direita. Termos tcnicos importantes - raiz de uma rvore: primeiro elemento da rvore; - n filho / n pai: o filho apontado pelo seu pai, ento um n que tem outro n em seu link direito/esquerdo pai do n que est no seu link direito/esquerdo e esse n por sua vez filho do dono do link que est apontando para ele; - folha de uma rvore: um n folha um n sem filhos (seus links so nulos); - n interno de uma rvore: um n que tem pelo menos um filho; - nvel de um n: distncia dele at a raiz (a raiz est no nvel 0), a cada link a distncia aumentada em 1 unidade.

Alguns tipos de rvore

Tipos de rvores Binrias

Exemplo de cdigo para rvores Binrias:

#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct stNo { int info; struct stNo *esq, *dir; } tNo ; tNo *cria_arvore( int ); tNo *cria_no( ); void pos_esq (tNo *, int ); void pos_dir (tNo *, int ); void main() { tNo *raiz, *p, *q; char linha[80], *numero; int num; gets(linha); numero = strtok(linha, " "); /* pega o primeiro numero da lista */ num = atoi(numero); raiz = cria_arvore(num); /* insere na raiz */

5
numero = strtok(NULL, " "); while (numero) { q = raiz; p = raiz; printf("Li numero %d\n", num); /* le novo numero */ num = atoi(numero); while (num != p->info && q) { /* procura na arvore */ p = q; if (num < p->info) q = p->esq; /* passa para arvore esquerda */ else q = p->dir; /* passa para direita */ } if (num == p->info) printf("O numero %d ja existe na arvore.\n", num); else { /* vou inserir o numero na arvore */ if (num < p->info) pos_esq(p, num); else pos_dir(p, num); } numero = strtok(NULL, " "); } /* fim do while (numero) */ } tNo *cria_arvore (int x) { tNo *p; p = cria_no (); if (p) { p->info = x; return p; } else { puts("Faltou espaco para alocar no."); exit(1); } } tNo *cria_no() { tNo *p; if ((p = return else { p->esq return } } (tNo *) malloc(sizeof(tNo))) == NULL) NULL; = NULL; p->dir = NULL; p;

void pos_esq(tNo *p, int x) { tNo *q;

6
if (p->esq) puts("Operacao de insercao a esquerda ilegal."); else { q = cria_arvore(x); p->esq = q; } }

void pos_dir(tNo *p, int x) { tNo *q; if (p->dir) puts("Operacao de insercao a direita ilegal."); else { q = cria_arvore(x); p->dir = q; } } void pre_ordem ( tipoNo *pt) { if (pt) { visita (pt); pre_ordem (pt->esq); pre_ordem (pt->dir); } } void em_ordem ( tipoNo *pt) { if (pt) { em_ordem (pt->esq); visita (pt); em_ordem (pt->dir); } } void em_ordem ( tipoNo *pt) { if (pt) { em_ordem (pt->esq); visita (pt); em_ordem (pt->dir); } } void visita (tNo *p) { int alt1, alt2; if (p->esq) alt1 = p->esq->altura; else alt1 = 0; if (p->dir) alt2 = p->dir->altura; else alt2 = 0; if (alt1>alt2) p->altura = alt1 + 1; else p->altura = alt2 + 1;

7
printf("info = %d ", p->info); printf("altura = %d\n", p->altura); } tNo *remover (tNo *tree, int num) { tNo *p, /* p aponta para o no a ser removido */ *q, /* q aponta para o pai do no */ *rp, /* rp aponta que ira substituir o no p */ *f, *s; /* sucessor do no p */ p = tree; q=NULL; /* procura o no com a chave num, p aponta para o no e q aponta para o pai do no */ while ( p && p->info != num) { q = p; if ( num < p->info) p = p->esq; else p = p->dir; } /* fim do while */ if (!p) return NULL; /* a chave nao existe na arvore */ /* agora iremos ver os dois primeiros casos, o no tem um filho no maximo */ if (p->esq == NULL) rp = p->dir; else if (p->dir == NULL) rp = p->esq; else { f=p; rp = p->dir; s = rp->esq; /* s e sempre o filho esq de rp */ while (s != NULL) { f = rp; rp = s; s = rp->esq; } /* neste ponto, rp e o sucessor em ordem de p */ if (f != p) { /* p nao e o pai de rp e rp == f->left */ f->esq = rp->dir; /* remove o no rp de sua atual posicao e o substitui pelo filho direito de rp rp ocupa o lugar de p */ rp->dir = p->dir; } /* define o filho esquerdo de rp de modo que rp ocupe o lugar de p */

8
rp->esq = p->esq; } /* insere rp na posicao ocupada anteriormente por p */ if (q == NULL) tree = rp; else if (p == q->esq) q->esq = rp; else q->dir = rp; free(p); return rp; }

Arvore Binaria AVL


As rvores AVL, cujo nome foi obtido a partir das iniciais de seus criadores russos Adelson-Velskii e Landis, so uma implementao

de um algoritmo para a criao de rvores binrias balanceadas. Uma vez que foi detectado o desbalanceamento da rvore aps uma insero, e que foi determinado o no do piv (onde o valor absoluto de FB maior que 1), passamos para a realizao do procedimento de balanceamento da rvore. Este procedimento consiste primeiramente de determinar em qual dos seguintes tipos de casos nos enquadramos: Tipo I : Se a subrvore esquerda maior que a subrvore direita (FB > 1) E a subrvore esquerda desta subrvore esquerda maior que a subrvore direita dela Ento realizar uma rotao simples para a direita; Tipo II : Se a subrvore esquerda maior que a subrvore direita (FB > 1) E a subrvore esquerda desta subrvore esq. menor ou igual que a subrvore direita Ento realizar uma rotao dupla para a direita; Tipo III: Se a subrvore esquerda menor que a subrvore direita (FB < -1) E a subrvore direita desta subrvore direita maior que a subrvore esquerda dela Ento realizar uma rotao simples para a esquerda; Tipo IV: Se a subrvore esquerda menor que a subrvore direita (FB < -1) E a subrvore direita desta subrvore direita menor que a subrvore esquerda dela Ento realizar uma rotao dupla para a esquerda;

Exemplo de cdigo para rvores Binrias AVL:


#include <stdexcept> #include <iostream> #ifndef AVL #define AVL

using namespace std;

namespace ED {

10

template <typename tipo=""> class AVLTree { public: AVLTree(); ~AVLTree(); //metodos principais void insere(Tipo el); void percursoEmOrdem(); void desaloca(); int tamanho(); int altura();

private: class Celula { public: Tipo el; Celula *esq, *dir; char h; char b; }; int height(Celula *x); void inorder_Walk(Celula *x); void removeCels(Celula *x);

11 void balanceia(Celula *&x); void atualiza(Celula *&x); void rotateLeft(Celula *&x); void rotateRight(Celula *&x); void desaloca(Celula *x); void insere(Celula* &x, Tipo &el); Celula *T; unsigned int nelem, h; };

//Construtor template <typename tipo=""> AVLTree<tipo>::AVLTree() { T = new Celula; T->esq = NULL; T->dir = NULL; nelem = 0; }

//Destrutor template <typename tipo=""> AVLTree<tipo>::~AVLTree() { this->desaloca(T); }

12

//Desaloca a arvore template <typename tipo=""> void AVLTree<tipo>::desaloca() { desaloca(T); }

//Desaloca a clula template <typename tipo=""> void AVLTree<tipo>::desaloca(Celula *x) { if (x == NULL) return; else{ desaloca(x->esq); desaloca(x->dir); delete x; atualiza(x); balanceia(x); } }

//Balanceamento template <typename tipo=""> void AVLTree<tipo>::balanceia(Celula *&x) {

13 if (x->b == 2) { if (x->esq->b == -1) rotateLeft(x->esq); rotateRight(x); } else if (x->b == -2) { if (x->dir->b == 1) rotateRight(x->dir); rotateLeft(x); } }

//Atualizao numero altura e balanceamento template <typename tipo=""> void AVLTree<tipo>::atualiza(Celula *&x) { unsigned char hesq = x->esq? (x->esq->h) : 0; unsigned char hdir = x->dir? (x->dir->h) : 0; x->b = hesq - hdir; x->h = 1 + (hesq > hdir? hesq : hdir); }

//Rotao Direita template <typename tipo=""> void AVLTree<tipo>::rotateRight(Celula *&x) { Celula *aux = x; x = x->esq;

14 aux->esq = x->dir; x->dir = aux; atualiza(aux); atualiza(x); }

//Rotao Esquerda template <typename tipo=""> void AVLTree<tipo>::rotateLeft(Celula *&x) { Celula *aux = x; x = x->dir; aux->dir = x->esq; x->esq = aux; atualiza(aux); atualiza(x); }

//Insero template <typename tipo=""> void AVLTree<tipo>::insere(Tipo el) { insere(T, el); }

template <typename tipo="">

15 void AVLTree<tipo>::insere(Celula* &x, Tipo &el) { if (!x) { x = new Celula(); x->el = el; nelem++; } else { if (x->el >= el) insere(x->esq, el); else insere(x->dir, el); atualiza(x); balanceia(x); } }

//Altura rvore template<typename tipo=""> int AVLTree<tipo>::altura() { return height(T); }

//Altura clula template<typename tipo=""> int AVLTree<tipo>::height(Celula *x) { int esq, dir; if (x == NULL) return 0;

16 esq = height(x->esq); dir = height(x->dir); if (esq > dir) return esq + 1; else return dir + 1; }

//Nmero de elementos arvore template <typename tipo=""> int AVLTree<tipo>::tamanho() { return (nelem); }

//Remanescncia BSTree ordenao template<typename tipo=""> void AVLTree<tipo>::inorder_Walk(Celula *x) { if (x == NULL) return; inorder_Walk(x->esq); cout << x->el << endl; inorder_Walk(x->dir); }

template<typename tipo="">

17 void AVLTree<tipo>::percursoEmOrdem() { this->inorder_Walk(T); }

Construo da rvore Binria


Primeiramente, um Array considerado afim de armazenar a freqncia com que os caracteres aparecem no texto do arquivo. Ao percorrer todo o arquivo, estas informaes so armazenadas no Array supracitado e a partir da que a construo da rvore binria ocorre de fato. O prximo passo verificar as duas menores freqncias dentro do Array. Elas sero consideradas folhas da rvore (bem como o prprio caracter que possui tal freqncia) e a soma de suas freqncias ser considerada seus pais. Essa soma armazenada em posies finais do Array em questo. interessante salientar que o algoritmo passa a desprezar as folhas criadas, o que um fator positivo no ponto de vista da eficincia do mesmo. O passo acima repetido considerando os outros elementos do Array bem como a soma de freqncias criada anteriormente.

Exemplificando insero em rvores Binrias:


Inserindo o valor 15:

15

18

Inserindo o valor 06:

15 06

Inserindo o valor 22:

15 06 22

Inserindo o valor 18:

15 06 18 22

19

Concluso
rvore binria uma estrutura de dados usada para oferecer rapidez e dinamismo nos softwares, seus elementos no esto armazenados de forma seqencial e no esto todos encadeados. Uma arvore binria um conjunto finito de elementos, onde cada elemento denominado n e o primeiro conhecido como raiz da rvore. Atravs dela, podemos buscar o elemento desejado em uma estrutura de forma organizada, na qual parti-se da raiz para os ns filhos em busca do elemento pesquisado, assim desde o incio podemos ir excluindo possibilidades esquerda ou direita se for menor ou maior que o elemento em teste. Com a utilizao da recursividade nesta rvore, torna-se mais gil e eficiente, e com uma boa estrutura para o armazenamento e busca dos elementos, por j estarem ordenados e pelo sistema de eliminao dos elementos caso seja maior ou menor.

20 As rvores binrias AVL so mais rpidas nas operaes de busca. A vantagem de uma rvore balanceada est na melhor eficincia em suas operaes de busca, pois, sendo a altura da balanceada bem menor, o nmero necessrio de comparaes tambm diminui diretamente

21

Referncias
rvores Binrias. Disponvel em: < http://www.allgoritmos.com/2009/07/arvorebinaria.html >. Acesso em 17 Nov. 2011.

ASCENCIO, Ana Fernanda Gomes; ARAJO, Graziela Santos de. Estrutura de dados algoritmos, anlise da complexidade e implementaes em JAVA e C/C+ +. So Paulo: Pearson Education, 2011.

FEOFILOFF, Paulo. rvores Binrias. Disponvel em: <http://www.ime.usp.br/~pf/algoritmos/aulas/bint.html>. Acesso em 16 Nov. 2011.

SANTOS, Carlos Alexandre Silva dos. RVORES BINRIAS. . Disponvel em: <http://www.al.urcamp.tche.br/infocamp/edicoes/marc06/arvores_binarias.pdf>. Acesso em 15 Nov. 2011.