Вы находитесь на странице: 1из 27

Abede Isaquiel Cugulo

Mohamad Satar Mohamed

Xavier Muiocha

Estruturas de Dados em Algoritmo

Árvores genericas, Árvores binarias, Árvores AVL

Licenciatura em Informatica com Habilidades em Engenharia de Redes e Engenharia de


Desenvolvimento de Software, 2° Ano, Pos Laboral

Universidade Licungo

Maio de 2020

Beira
Abede Isaquiel Cugulo

Mohamad Satar Mohamed

Xavier Muiocha

Estruturas de Dados em Algoritmo

Árvores genericas, Árvores binarias, Árvores AVL

Licenciatura em Informatica com Habilidades em Engenharia de Redes e Engenharia de


Desenvolvimento de Software, 2 Ano, Pos Laboral

Docente:

Alfredo Maleca

Universidade Licungo

Maio de 2020

Beira
Indice
Introdução..................................................................................................................................1

Árvore........................................................................................................................................2

Definição de árvore....................................................................................................................2

Representacao............................................................................................................................2

Algoritmos..................................................................................................................................3

Arvore binaria............................................................................................................................3

Definições de árvores binárias...................................................................................................3

Definições em teoria dos grafos.................................................................................................4

Percursos em árvore...................................................................................................................6

Ordem simétrica.....................................................................................................................6

Contagem dos nós...................................................................................................................8

Métodos para representação de árvores binárias........................................................................9

Arvore AVL...............................................................................................................................9

Uma árvore AVL....................................................................................................................9

Estrutura...............................................................................................................................10

Balanceamento.........................................................................................................................10

Busca........................................................................................................................................11

Algoritmo de busca...............................................................................................................11

Inserção.................................................................................................................................12

Aplicações............................................................................................................................12

Dicionários...........................................................................................................................12

Geometria Computacional....................................................................................................12

Conjuntos..............................................................................................................................12

Arvore de pesquisa...................................................................................................................13

Operacoes.............................................................................................................................13

Busca....................................................................................................................................13
Aplicações............................................................................................................................13

AB Balanceada vs AB Perfeitamente Balanceada...................................................................14

Estrutura de Dados...............................................................................................................15

Execução do Trabalho..........................................................................................................16

Altura Negra.........................................................................................................................16

rbCheck....................................................................................................................................17

Árvores de Decisão..................................................................................................................17

Árvores de decisão...............................................................................................................18

Implementação.....................................................................................................................18

Ambiente computacional......................................................................................................19

Java.......................................................................................................................................19

Conclusão.................................................................................................................................21

Bibliografia..............................................................................................................................22
Introdução
As árvores são estruturas de dados baseadas em listas encadeadas que possuem um nó
superior também chamado de raiz que aponta para outros nós, chamados de nós filhos, que
podem ser pais de outros nós. Uma árvore de busca binária tem as seguintes propriedades
todos os elementos na subárvore esquerda de um determinado nó n são menores que n; todos
os elementos na subárvore direita de um determinado nó n são maiores ou iguais a n.

1
Árvore
No contexto da programação, engenharia de software e ciência da computação, é uma das
mais importantes estruturas de dados não lineares. Herda as características das topologia em
árvore. Conceitualmente diferente das listas, em que os dados se encontram numa sequência,
nas árvores os dados estão dispostos de forma hierárquica, seus elementos se encontram
"acima" ou abaixo de outros elementos da árvore.

Uma árvore é formada por um conjunto de elementos que armazenam informações chamados
nodos (ou nós). Toda a árvore possui o elemento chamado raiz, que possui ligações para
outros elementos denominados ramos ou filhos. Estes ramos podem estar ligados a outros
elementos que também podem possuir outros ramos. O elemento que não possui ramos é
conhecido como nó folha, nó terminal ou nó externo.

Definição de árvore
Formalmente, definimos uma árvore {\displaystyle T}T como um conjunto finito de zero ou
mais nodos tal que[3]:

se o número de nodos = {\displaystyle 0}{\displaystyle 0}, temos uma árvore vazia, ou

se o número de nodos > {\displaystyle 0}{\displaystyle 0}

existe um nó especialmente denominado raiz de {\displaystyle T}T

os nós restantes formam {\displaystyle m\geq 0}{\displaystyle m\geq 0} conjuntos disjuntos


{\displaystyle p_{1},p_{2},...,p_{m}}{\displaystyle p_{1},p_{2},...,p_{m}}, cada um desses
conjuntos é uma árvore em si, chamada subárvore da raiz de {\displaystyle T}T, ou
simplesmente subárvore.

O número máximo de filhos em um nodo é chamado ordem da árvore. Uma árvore binária é
aquela de ordem 2, i.e., em que cada elemento possui no máximo 2 filhos.

Representacao
Há diversas formas de representação de uma árvore: hierárquica, diagrama de inclusão,
diagrama de barras, numeração por níveis, por aninhamento.

A hierárquica é parecida com um organograma de uma empresa, linhas unem dois nodos e
indicam o relacionamento lógico entre eles. Tradicionalmente desenha-se a raiz na parte
superior e todos os nodos subordinados na parte inferior, mas o contrário também é possível.
Na figura ao lado, o item (a) é um exemplo desta representação.
2
Diagrama de inclusão, um círculo representa cada nodo e seus nodos descendentes são
inseridos dentro do círculo de seus pais. Também conhecida como diagrama de Venn, é
muito utilizada na representação de conjuntos. O item (c) da figura ao lado mostra a árvore
do item (a) usando diagrama de inclusão.

Algoritmos
Uma das operações importantes consiste em percorrer cada elemento da árvore uma única
vez. Esse percurso, também chamado de travessia da árvore, pode ser feito em pré-ordem (os
filhos de um nó são processados após o nó) ou em pós-ordem (os filhos são processados antes
do nó). Em árvores binárias é possível ainda fazer uma travessia em-ordem, em que se
processa o filho à esquerda, o nó, e finalmente o filho à direita. O algoritmo abaixo descreve
uma travessia pré-ordem: PercursoPreordem(nó): Processa nó Para cada filho de nó (se
houver) Executa recursivamente PercursoPreordem(filho).

Arvore binaria
Uma árvore binária é uma estrutura de dados caracterizada por:

Ou não tem elemento algum (árvore vazia). Ou tem um elemento distinto, denominado raiz,
com dois ponteiros para duas estruturas diferentes, denominadas subárvore esquerda e
subárvore direita. Perceba que a definição é recursiva e, devido a isso, muitas operações
sobre árvores binárias utilizam recursão. É o tipo de árvore mais utilizado na computação. A
principal utilização de árvores binárias são as árvores binárias de busca.

Definições de árvores binárias


Os nós de uma árvore binária possuem graus zero, um ou dois. Um nó de grau zero é
denominado folha. Em uma árvore binária, por definição, cada nó poderá ter até duas folhas,
sendo que ela se compara com a ABB (árvore binária de busca), apesar de não ter a
propriedade da mesma ("na abb, existe uma regra na inserção"). A profundidade de um nó é a
distância deste nó até a raiz. Um conjunto de nós com a mesma profundidade é denominado
nível da árvore. A maior profundidade de um nó, é a altura da árvore. Uma árvore
"estritamente binária" é uma árvore na qual todo nó tem zero ou duas folhas. Existem autores,
porém, que adotam essa definição para o termo quase completa, e utilizam o termo completa
apenas para árvores em que todos os níveis têm o máximo número de elementos.

3
Definições em teoria dos grafos
Em teoria dos grafos, uma árvore binária é definida como um grafo acíclico, conexo, dirigido
e que cada nó não tem grau maior que 2. Assim sendo, só existe um caminho entre dois nós
distintos. E cada ramo da árvore é um vértice dirigido, sem peso, que parte do pai e vai para o
filho.

Algoritmo da inserção em C:

void inserir(struct No **pRaiz, int numero){

if(*pRaiz == NULL){

* pRaiz = (struct No *) malloc(sizeof(struct No));

(*pRaiz)→pEsquerda = NULL;

(*pRaiz)→pDireita = NULL;

(*pRaiz)→numero = numero;

}else{

if(numero <(*pRaiz)→numero)

inserir(&(*pRaiz)→pEsquerda, numero));

else

inserir(&(*pRaiz)→pDireita, numero));

Algoritmo da inserção em Java:

public class Arvore {

public No raiz;

class No {

Integer valor;

No filhoEsquerdo;
4
No filhoDireito;

public No(Integer valor) {

this.valor = valor;

public No inserir(Integer valor) {

return this.inserir(new No(valor), raiz);

private No inserir(No novo, No anterior) {

if (raiz == null) {

raiz = novo;

return raiz;

if (anterior != null) {

if (novo.valor <= anterior.valor) {

anterior.filhoEsquerdo = this.inserir(novo, anterior.filhoEsquerdo);

} else if (novo.valor > anterior.valor) {

anterior.filhoDireito = this.inserir(novo, anterior.filhoDireito);

} else {

return null;

} else {

anterior = novo;

return anterior;
5
}

Percursos em árvore
Existem três tipos de percursos: Percurso em ordem simétrica(em-ordem), pré-ordem e pós-
ordem.

Ordem simétrica
O algoritmo recursivo desse percurso em C é:

void emOrdem(struct No *pNo) {

if(pNo != NULL) {

emOrdem(pNo→pEsquerda);

visita(pNo);

emOrdem(pNo→pDireita);

O algoritmo recursivo desse percurso em Java é:

public void emOrdem(No no) {

if (no != null) {

emOrdem(no.filhoEsquerdo);

System.out.println(no.valor);

emOrdem(no.filhoDireito);

6
Pré-ordem

O algoritmo recursivo desse percurso em C é:

void preOrdem(Struct No *pNo){

if(pNo != NULL){

visita(pNo);

preOrdem(pNo→pEsquerda);

preOrdem(pNo→pDireita);

O algoritmo recursivo desse percurso em Java é:

public void preOrdem(No no) {

if (no != null){

System.out.println(no.valor);

preOrdem(no.filhoEsquerdo);

preOrdem(no.filhoDireito);

Pós-ordem

O algoritmo recursivo desse percurso em C é:

void posOrdem(Struct No *pNo){

if(pNo != NULL){

posOrdem(pNo→pEsquerda);

posOrdem(pNo→pDireita);

visita(pNo);
7
}

O algoritmo recursivo desse percurso em Java é:

public void posOrdem(No no) {

if (no != null) {

posOrdem(no.filhoEsquerdo);

posOrdem(no.filhoDireito);

System.out.println(no.valor);

Contagem dos nós


Uma árvore binária que tenha todas as suas folhas completas possui o número de nós
{\displaystyle (N)}{\displaystyle (N)}, em relação ao total de níveis da árvore {\displaystyle
(n)}{\displaystyle (n)}, dado pela seguinte expressão:

{\displaystyle {\text{Nº de nós }}(N)=2^{n}-1}{\displaystyle {\text{Nº de nós }}(N)=2^{n}-


1}

Exemplos a partir de programação

Em Java

public int contagem(No no){

return (no == null) ? 0 : 1 + contagem(no.filhoEsquerdo) + contagem(no.filhoDireito);

Em C

int contagem(struct node *tree) {

return (tree != NULL) ? (contagem(tree->left) + contagem(tree->right) + 1) : 0;

8
Métodos para representação de árvores binárias
Uma das maneiras mais simples de representar árvores binárias em linguagens de
programação é por meio de arranjos unidimensionais (vetores). Caso a raiz esteja na posição
zero, dado um nó de índice i qualquer, os seus filhos terão índices {\displaystyle 2i+1}
{\displaystyle 2i+1} e {\displaystyle 2i+2}{\displaystyle 2i+2} e o seu pai terá índice piso((i
- 1)/2). Caso a raiz esteja na posição um, os filhos terão índices {\displaystyle 2i}
{\displaystyle 2i} e {\displaystyle 2i+1}{\displaystyle 2i+1} e o pai terá índice piso(i/2). Essa
implementação é utilizada para representar árvores completas ou quase completas. Heaps,
que são árvores binárias quase completas são implementadas na forma de um vetor de uma
maneira bastante eficiente.

Apesar da simplicidade, essa representação requer uma grande quantidade de memória


contígua para o armazenamento de árvores grandes, o crescimento desta é díficil de
implementar e manter e pode haver grande quantidade de desperdício de memória. Em uma
linguagem que possua suporte a estruturas e referências (por exemplo pascal e C), as árvores
podem ser implementadas a partir de nós, com um, ou mais, campos para a(s)
informação(ões) principal(is) e dois campos apontadores especiais, denominados esquerda e
direita, que fazem referência às subárvores esquerda e direita, respectivamente. Algumas
vezes, há um apontador para o pai. Em um nó do tipo folha, os campos apontadores possuem
valores especiais (nil em Pascal e "NULL" em C).

Arvore AVL
Uma árvore binária T é denominada AVL quando, para qualquer nó de T, as alturas de suas
duas subárvores, esquerda e direita, diferem em módulo de até uma unidade.

Uma árvore AVL


Pela definição fica estabelecido que todos os nós de uma árvore AVL devem respeitar a
seguinte propriedade:

|hd(u) - he(u)| ≤ 1, onde hd(u) é a altura da subárvore direita do nó u e he(u) é a altura da


subárvore esquerda do nó u.

O valor hd(u) - he(u) é denominado fator de balanço do nó. Quando um nó possui fator de
balanço com valor -1, 0 ou 1 então o mesmo é um nó regulado. Todos os nós de uma árvore
AVL são regulados, caso contrário a árvore não é AVL.

9
Estrutura
Proposta de estrutura dos nós de uma árvore AVL básica, com chave do tipo inteiro:

tipo No_AVL = registro

chave: inteiro;

fb: inteiro; // Fator de Balanço

esq: ^No_AVL; // aponta subárvore esquerda

dir: ^No_AVL; // aponta subárvore direita

fim;

O campo chave armazena o valor da chave. Os campos esq e dir são ponteiros para as
subárvores esquerda e direita, respectivamente. O campo fb armazena o fator de balanço.

Definição da estrutura da árvore:

tipo Arvore_AVL = registro

raiz: ^No_AVL;

// definição de outros campos de interesse

fim;

Balanceamento
Toda árvore AVL é balanceada, isto é, sua altura é O(log n).

A vantagem do balanceamento é possibilitar que a busca seja de complexidade O(log n).


Entretanto, as operações de inserção e remoção devem possuir custo similar. No caso da
árvore AVL, a inserção e remoção têm custo O(log n).

Por definição, todos os nós da AVL devem ter fb = -1, 0 ou 1.

Para garantir essa propriedade, a cada inserção ou remoção o fator de balanço deve ser
atualizado a partir do pai do nó inserido até a raiz da árvore. Na inserção basta encontrar o
primeiro nó desregulado (fb= -2 ou fb= 2), aplicar o operação de rotação necessária, não
havendo necessidade de verificar os demais nós. Na remoção a verificação deverá prosseguir
até a raiz, podendo requerer mais de uma rotação.

10
Busca
A busca é a mesma utilizada em árvore binária de busca. A busca pela chave de valor K
inicia sempre pelo nó raiz da árvore. Seja pt_u um ponteiro para o nó u sendo verificado.
Caso o pt_u seja nulo então a busca não foi bem sucedida (K não está na árvore ou árvore
vazia). Verificar se a chave K igual pt_u->chave (valor chave armazenado no nó u), então a
busca foi bem sucedida. Caso contrário, se K < pt_u->chave então a busca segue pela
subárvore esquerda; caso contrário, a busca segue pela subárvore direita.

Algoritmo de busca
busca_AVL(@pt_u:^no_AVL, K:inteiro):logico;

inicio

se pt_u é NULO então retornar Falso;

se K = pt_u->chave então retornar Verdadeiro;

senão se K < pt_u->chave então

retornar busca_AVL(u->esq, K);

senão retornar busca_AVL(u->dir, K);

fim.

Exemplo de algoritmo de busca em Java.

// O método de procura numa AVL é semelhante ao busca binária de uma árvore binária de
busca comum.

public BSTNode<T> search(T element) {

return search(element, this.root);

// Método auxiliar à recursão.

private BSTNode<T> search(T element, BSTNode<T> node) {

if (element == null || node.isEmpty()) {

return new BSTNode<T>();

11
if (node.isEmpty() || node.getData().equals(element)) {

return node;

} else if (node.getData().compareTo(element) > 0) {

return search(element, node.getLeft());

} else {

return search(element, node.getRight());

}}

Inserção
Para inserir um novo nó de valor K em uma árvore AVL é necessária uma busca por K nesta
mesma árvore. Após a busca o local correto para a inserção do nó K será em uma subárvore
vazia de uma folha da árvore. Depois de inserido o nó, a altura do nó pai e de todos os nós
acima deve ser atualizada. Em seguida o algoritmo de rotação simples ou dupla deve ser
acionado para o primeiro nó pai desregulado.

Aplicações
A árvore AVL é muito útil pois executa as operações de inserção, busca e remoção em tempo
O(log n) sendo inclusive mais rápida que a árvore rubro-negra para aplicações que fazem
uma quantidade excessiva de buscas, porém esta estrutura é um pouco mais lenta para
inserção e remoção. Isso se deve ao fato de as árvores AVL serem mais rigidamente
balanceadas.

Dicionários
Árvore AVL pode ser usada para formar um dicionário de uma linguagem ou de programas,
como os opcodes de um assembler ou um interpretador.

Geometria Computacional
Árvore AVL pode ser usada também na geometria computacional por ser uma estrutura
muito rápida. Sem uma estrutura com complexidade O(log n) alguns algoritmos da geometria
computacional poderiam demorar dias para serem executados.

Conjuntos
Árvore AVL podem ser empregadas na implementação de conjuntos, principalmente aqueles
cujas chave não são números inteiros. A complexidade das principais operações de conjuntos
usando árvore AVL:
12
Inserir - O(log n);

Remover - O(log n);

Pertence - O(log n);

União - O(n.log n);

Interseção - O(n.log n)

Arvore de pesquisa
Em Ciência da computação, uma árvore binária de busca (ou árvore binária de pesquisa) é
uma estrutura de dados de árvore binária baseada em nós, onde todos os nós da subárvore
esquerda possuem um valor numérico inferior ao nó raiz e todos os nós da subárvore direita
possuem um valor superior ao nó raiz (esta é a forma padrão, podendo as subárvores serem
invertidas, dependendo da aplicação). O objetivo desta árvore é estruturar os dados de forma
a permitir busca binária.

Operacoes
Busca
A busca em uma árvore binária por um valor específico pode ser um processo recursivo ou
iterativo. Será apresentado um método recursivo. A busca começa examinando o nó raiz. Se a
árvore está vazia, o valor procurado não pode existir na árvore. Caso contrário, se o valor é
igual a raiz, a busca foi bem sucedida. Se o valor é menor do que a raiz, a busca segue pela
subárvore esquerda. Similarmente, se o valor é maior do que a raiz, a busca segue pela
subárvore direita. Esse processo é repetido até o valor ser encontrado ou a subárvore ser nula
(vazia). Se o valor não for encontrado até a busca chegar na subárvore nula, então o valor não
deve estar presente na árvore.

Aplicações
Percursos em ABB

Em uma árvore binária de busca podem-se fazer os três percursos que se fazem para qualquer
árvore binária (percursos em inordem, pré-ordem e pós-ordem). É interessante notar que,
quando se faz um percurso em ordem em uma árvore binária de busca, os valores dos nós
aparecem em ordem crescente. A operação "Percorre" tem como objetivo percorrer a árvore
numa dada ordem, enumerando os seus nós. Quando um nó é enumerado, diz-se que ele foi
"visitado".

13
Pré-ordem (ou profundidade):

 Visita a raiz
 Percorre a subárvore esquerda em pré-ordem
 Percorre a subárvore direita em pré-ordem

Ordem Simétrica:

 Percorre a subárvore esquerda em ordem simétrica


 Visita a raiz
 Percorre a subárvore direita em ordem simétrica

Pós-ordem:

 Percorre a subárvore esquerda em pós-ordem


 Percorre a subárvore direita em pós-ordem
 Visita a raiz

AB Balanceada vs AB Perfeitamente Balanceada


 Seja hb (n) a altura de uma AB balanceada. O seguinte resultado foi demonstrado:
log2 (n+1)  hb (n)  1.4404 log2 (n+2) – 0.328  Ou seja: Uma AB Balanceada
nunca terá altura superior a 45% da altura de sua correspondente Perfeitamente
Balanceada.
 As operações numa AB Balanceada serão portanto da O(log2n);
 Para uma ABB aleatória, foi mostrado que o número esperado de comparações para
recuperar um registro qualquer é cerca de 1,39*log2 (n).  ou seja, 39% pior do que o
custo do acesso em uma árvore perfeitamente balanceada isto é: o balanceamento a
cada operação aumenta o tempo e garante um desempenho melhor que numa árvore
aleatória de, no máximo, 39% (o pior caso é muito raro);
 Essa estratégia é aconselhável apenas se o número de buscas for muito maior do que
o de inserções;
 A conservação do balanceamento pode ser mais simples se relaxarmos a condição de
perfeitamente balanceada para balanceada apenas;

Uma árvore vermelho-preto é uma árvore de busca binária que contém uma informação extra
por nó, que é sua cor, que pode ser vermelha ou preta. Na implementação, cada nó possui os

14
atributos cor, chave, esquerda, direita e pai. Se um filho de um nó ou seu pai não existe, o
ponteiro correspondente aponta para uma variável sentinela, chamada “nil”.

A árvore vermelho-preto deve satisfazer as seguintes propriedades:

1. Todo nó da árvore é vermelho ou preto.

2. O nó raiz é preto.

3. Toda folha (nil) é preta.

4. Se um nó é vermelho, então seus filhos são pretos.

5. Para cada nó, todos os caminhos de um nó até seus descendentes possuem o mesmo
número de nós pretos.

Estrutura de Dados
A árvore implementada em Java contém 2 atributos, uma referência ao nó raiz, e uma
referência sentinela aos nós folha e pai do raiz, que simboliza um nó nulo. A árvore está
descrita no arquivo RBTree.java

public class RBTree <T extends Comparable<T>> {

private RBElement<T> root;

private RBElement<T> nil;

nil = new RBElement<T>();

nil.setColor(Color.BLACK);

root = nil;

// ...

Na instanciação da árvore, o nó raiz aponta para nil, simbolizando uma árvore vazia. Para
implementar a lógica da árvore binária, que identifica se um elemento deve ser adicionado
como filho à esquerda ou filho da direita, utilizamos uma referência genérica T que deve

15
implementar a interface Comparable. Sendo assim, nossa árvore poderá conter números,
strings ou qualquer outra informação que seja possível comparar.

Já a estrutura de cada nó foi implementada da seguinte forma:

public class RBElement<T extends Comparable<T>> {

enum Color {

RED, BLACK;

protected Color color = Color.BLACK;

protected RBElement<T> p;

protected RBElement<T> left;

protected RBElement<T> right;

protected T key;

public RBElement() {

public RBElement(T z) {

key = z;

A classe contém a informação das referências aos elementos pai, filhos da esquerda e direita e
sua cor. Os elemento da árvore está descrito no arquivo RBElement.java

Execução do Trabalho
Um arquivo Main.java foi criado para realizar a interação descrita no trabalho. Uma leitura de
arquivo que define as operações de inserção e remoção de palavras em uma árvore.

Altura Negra
A altura negra de é definida como sendo o número de nós pretos de um nó X até suas folhas,
sem incluir o próprio nó X. Pela propriedade 5 da árvore vermelho-preto a definição de altura
negra é satisfeita
16
Para cada nó, todos os caminhos de um nó até seus nós descendentes possuem o mesmo
número de nós pretos.

Sendo assim, foi definida uma função que recupera a altura negra da raiz da árvore. Esta
função é utilizada como base para implementação do método rbCheck.

public int blackHeight() {

if(isNil(root)) {

return 0;

int blackHeight = 0;

RBElement<T> e = root.left;

while ( !isNil(e) ) {

if(e.color.equals(Color.BLACK)) {

blackHeight++;

e = e.left;

return blackHeight;

rbCheck
A função rbCheck é uma chamada que ocorre em uma instância da árvore. O procedimento
realiza uma chamada recursiva no método printRbCheck, que recebe o nó que está sendo
visitado e a sua altura negra. Em sua chamada inicial, definimos a altura negra da árvore, que
é atualizada a cada chamada recursiva, se necessário.

Árvores de Decisão
Uma árvore de decisão pode ser vista como um fluxograma que representa de forma gráfica o
processo de tomada de decisão. Empresas podem utilizá-la diante de situações problema do

17
dia a dia, como conceder um empréstimo a um potencial cliente ou realizar análises
financeiras, por exemplo.

Por outro lado, os indivíduos comuns podem necessitar delas para serem ajudados em algum
processo do dia a dia, como a compra de um carro. O processo de decisão faz parte da vida
do ser humano, entretanto, para analisar grandes volumes de dados são necessários modelos
computacionais que possam fornecer certa precisão e agilidade.

Árvores de decisão
Árvores de decisão são modelos estatísticos utilizados em problemas de predição
supervisionada, onde um conjunto de atributos é utilizado para predizer o valor de um
atributo de saída (resultado), sendo o mapeamento destas entradas para a saída denominado
modelo preditivo. Os dados usados para estimar um modelo preditivo são um conjunto de
casos (observações, exemplos) que contém valores das entradas e do resultado. Este modelo é
aplicado em novos casos onde o resultado é desconhecido. Uma árvore de decisão possui este
nome pois o modelo preditivo pode ser representado numa estrutura semelhante a uma
árvore. A árvore de decisão é sempre lida de forma descendente, iniciando-se pelo nó raiz.
Cada nó interno representa uma quebra baseada nos valores de um atributo de entrada, o qual
pode aparecer em outras quebras na árvore. Os nós terminais de uma árvore são chamados
folhas, que representam o resultado predito. Quando o resultado é discreto, o modelo é
chamado de árvore de classificação, onde as folhas fornecem a classe predita e a sua
probabilidade. Quando o resultado é contínuo, o modelo é chamado de árvore de regressão.
Neste caso, as folhas fornecem apenas uma predição de valor do resultado. O método padrão
usado no crescimento da árvore de decisão é baseado em partições recursivas, que é um
algoritmo guloso descendente. Começando no nó raiz, um número de quebras pertinentes a
um atributo de entrada é examinado. Para entradas contínuas, as divisões são segmentos
disjuntos dos valores de entrada, enquanto que para entradas discretas as divisões são
subconjuntos disjuntos das categorias de entrada.

Implementação
Existem vários classificadores que constroem árvore de decisão, sendo que geralmente eles
geram toda a árvore para depois podá-la. Esta fase de poda serve para melhorar a precisão e
prevenir contra o overfitting. Entretanto, a geração de uma árvore de decisão em duas fases
distintas pode resultar num desperdício de esforço considerado se uma subárvore inteira

18
construída na primeira fase for podada na segunda fase. Se durante a fase de construção,
antes de dividir um nó, puder ser concluído que ele será podado na próxima fase, este esforço
pode ser evitado. Desta forma, como as leituras dos dados são repetidas várias vezes para
gerar uma subárvore, pode-se conseguir reduções significativas de I/O e melhorar o
desempenho do processo.

Ambiente computacional
Com o intuito de avaliar o desempenho do algoritmo PUBLIC implementado em Java
utilizou-se o Oracle 8i v.8.1.7 (release 3) configurado em um microcomputador Pentium II
350Mhz com 128MB de memória principal e executando o Windows NT Server 4.0, onde foi
instalado o pacote Java SDK 2 v.1.3.0. O acesso da aplicação Java ao banco de dados Oracle
é realizado através do driver JDBC Thin. Com o objetivo de ter uma referência para
comparação de desempenho, este algoritmo PUBLIC também foi implementado numa
arquitetura fortemente acoplada, onde os procedimentos foram escritos em Oracle PL/SQL,
que é uma extensão do SQL, e armazenados dentro do dicionário de dados do Oracle. A
utilização da linguagem PL/SQL só foi possível devido à sua capacidade de trabalhar com
SQL dinâmico, não possuindo similar em outros bancos de dados. Uma característica
operacional do PL/SQL é que, por ser uma linguagem de programação proprietária, sua
utilização fica restrita aos bancos de dados da Oracle. Uma avaliação de desempenho de uma
abordagem fortemente acoplada com PL/SQL em ambiente Oracle paralelo é mostrada em
SOUSA et al. [7]. Observa-se que, em ambas as implementações (Java e PL/SQL), os
comandos SQL executados são os mesmos.

Java
Em três anos, o Java passou de uma linguagem de programação usada no desenvolvimento de
simples programas com interface gráfica que podiam ser enviados pela Web para uma
plataforma para desenvolvimento e disponibilização de aplicações corporativas e de Internet.
O Java tornou-se muito popular entre os desenvolvedores de aplicação porque os deixou mais
produtivos e por ser uma linguagem moderna, robusta e orientada a objeto. Além disso,
segundo ORACLE, a popularidade sem precedentes do Java é decorrente de três benefícios:

1. O desenvolvimento de aplicações é mais simples: o Java oferece características como o


suporte para rede e para programação concorrente (multithreading), que tornam o
desenvolvimento de aplicações mais simples que a maioria dos seus predecessores;

19
2. As aplicações são independentes de plataforma: o mesmo código binário Java pode ser
executado em qualquer plataforma que suporta uma máquina virtual Java, incluindo
mainframes;

3. As aplicações podem ser desenvolvidas como componentes: o Java oferece um modelo de


componentes, o JavaBeans, que permite aos desenvolvedores definir e encapsular
componentes que podem ser montados com componentes escritos por outros
desenvolvedores.

20
Conclusão
Neste artigo procurou-se demonstrar alguns conceitos e como essa importante estrutura de
dados é implementada na prática na linguagem de programação Java. As suas vantagens,
peculiaridades que lhe fazem ser uma árvore binária, sua implementação e detalhes da sua
execução foram demonstradas neste artigo.

21
Bibliografia
 Cormen, Thomas; Leiserson, Charles; Rivest, Ronald; Stein, Clifford (2001). «18».
Introduction to Algorithms (em inglês) 2 ed. [S.l.]: MIT Press and McGraw-Hill.
 Folk, Michael; Zoellick, Bill (1992). File Structures (em inglês) 2 ed. [S.l.]: Addison-
Wesley. 590 páginas.
 Knuth, Donald (1998). The Art of Computer Programming. Sorting and Searching
(em inglês). 3 2 ed. [S.l.]: Addison-Wesley.

22

Вам также может понравиться