Árvores Binárias - continuação



Documentos relacionados
INF 1007 Programação II

INF1007: Programação 2 10 Árvores Binárias. (c) Dept. Informática - PUC-Rio 1

Linguagem C: Árvores Binarias

Estruturas de Dados. Prof. Gustavo Willam Pereira Créditos: Profa. Juliana Pinheiro Campos

Árvore Binária de Busca

INF PROGRAMAÇÃO II LISTA DE EXERCÍCIOS 15

Métodos Computacionais. Árvores

EAD Árvore árvore binária

2ª Lista de Exercícios

EAD Árvore - representação usando listas ligadas

Busca. Pesquisa sequencial

Estruturas de Dados I

BUSCA EM LISTAS LISTAS SEQÜENCIAIS, LISTAS SIMPLESMENTE E DUPLAMENTE ENCADEADAS E LISTAS CIRCULARES

Árvores Binárias de Busca

Figura 13.1: Um exemplo de árvore de diretório.

ALGORITMOS E ESTRUTURAS DE DADOS CES-11 CES-11 CES-11

Algoritmos e Estruturas de Dados 2

Pesquisa em Memória Primária. Algoritmos e Estruturas de Dados II

- UNIVERSIDADE DO VALE DO RIO DOS SINOS CIÊNCIAS EXATAS E TECNOLÓGICAS Curso: Informática / Ciência da Computação

PROGRAMAÇÃO II 4. ÁRVORE

Algoritmos e Estruturas de Dados: Árvore Binária

1. Introdução Definição Conceitos relacionados... 2

INF 1005 Programação I

Árvores Binárias de Busca

Estruturas de Dados Aula 15: Árvores 17/05/2011

Árvores binárias de pesquisa com balanceamento. Algoritmos e Estruturas de Dados II

struct LISTA item quant

Pesquisa em Memória Primária. Prof. Jonas Potros

struct arv { char info; struct arv* esq; struct arv* dir; };

Algoritmos e Estruturas de Dados

Trabalho 3: Agenda de Tarefas

Pesquisa Sequencial e Binária

Índice. Capítulo 2 Estrutura de Dados sequencial com armazenamento sequencial

Exercício 1. Tabela 1: Cadastro de usuários, senhas e privilégios (exemplo). Login Senha Privilégio Armamento

Árvores Binárias Balanceadas

ESTRUTURAS DE DADOS AVANÇADAS (INF 1010) (a) Seja um TAD definido por uma lista circular implementada em um vetor.

FACULDADE CAMPO LIMPO PAULISTA MESTRADO EM CIÊNCIA DA COMPUTAÇÃO. Projeto e Análise de Algoritmos II Lista de Exercícios 2

Árvores. Algoritmos e Estruturas de Dados 2005/2006

INF 1620 P1-10/04/02 Questão 1 Nome:

Algoritmos e Estruturas de Dados: Árvore Binária de Busca

Algoritmos de Busca em Tabelas

Listas (Parte 2) Túlio Toffolo BCC202 Aula 10 Algoritmos e Estruturas de Dados I

1ª versão. #include <stdio.h> #include <string.h> #include <stdlib.h> #define maxdiscos 1000

20 Caracteres - Tipo char

DAS5102 Fundamentos da Estrutura da Informação

CIÊNCIA DA COMPUTAÇÃO PROVA PARA TRANSFERÊNCIA

Introdução. Manipulação de arquivos em C. Estrutura de Dados II Prof Jairo Francisco de Souza

Programas operam sobre dados. Dados são relacionados e possuem estrutura. Como representar e manipular dados em um computador

Capítulo 2: Introdução à Linguagem C

Estruturas de Dados. Árvores AVL. Cesar Tadeu Pozzer. Curso de Ciência da Computação UFSM (12/12/2007)

Algoritmos e Estrutura de Dados III. Árvores

ESTRUTURAS DE DADOS I. Notas de Aula. Prof. Dr. Gilberto Nakamiti

Edwar Saliba Júnior. Dicas, Comandos e Exemplos Comparativos entre Linguagem Algorítmica e Linguagem C

Sistemas Operacionais e Introdução à Programação. Programação com linguagem C

Métodos Computacionais. Fila

ESTRUTURA DE DADOS DCC013

Pedro Vasconcelos DCC/FCUP. Programação Funcional 15 a Aula Árvores de pesquisa

INF 1005 Programação I

MC-102 Aula 19 Registros

Estruturas de entrada e saída

Árvore Binária de Busca. Algoritmos e Estrutura de Dados II. Operações Busca e Sucessor. Árvore Binária de Busca. Árvores Rubro-Negras

Estruturas de Dados. Parte dos slides a seguir são adaptações, extensões e traduções para C dos originais:

Pesquisa em Memória Primária. Prof. Jonas Potros

Aula T20 BCC202 Pesquisa (Parte 2) Árvores de Pesquisa. Túlio Toffolo

Algoritmos e Programação Estruturada

Métodos de Pesquisa em Memória Primária

DAINF - Departamento de Informática

PROVA P2 INF /10/2014 Programação II

Ficheiros binários 1. Ficheiros binários

- UNIVERSIDADE DO VALE DO RIO DOS SINOS CIÊNCIAS EXATAS E TECNOLÓGICAS Curso: Informática / Ciência da Computação

Vetores. Vetores. Figura 1 Exemplo de vetor com 10 elementos

Na disciplina de Cálculo Numérico, vamos trabalhar com a linguagem C++ e o compilador que vamos usar é o Dev C++.

INF 1007 Programação II

9 Comandos condicionais

Estrutura da linguagem de programação C Prof. Tiago Eugenio de Melo tiago@comunidadesol.org

Filas COMANDOS EM C++ PARA IMPLEMENTAÇÃO DE UMA FILA. Biblioteca padrão <queue>

Árvore B UNITINS ANÁLISE E DESENVOLVIMENTO DE SISTEMAS 3º PERÍODO 43

Linguagem de Programação I

Busca em Memória. Secundária

10. Listas Encadeadas

Aula 1 Tipo Abstrato de Dados

Conceitos Importantes:

ÁRVORE BINÁRIA DE BUSCA TDA-ABB

1 Resumo: Strings e vetores de caracteres. Departamento de Ciência da Computação IME/USP

Universidade Federal do Vale do São Francisco. Estruturas de Dados. Professor: Marcelo Santos Linder

ESTRUTURAS DE DADOS II MSc. Daniele Carvalho Oliveira

Tipos de Dados, Tipos Abstratos de Dados Estruturas de Dados

Implementando uma Classe e Criando Objetos a partir dela

Curso de Programação Computadores

GABARITO EXERCÍCIOS ÁRVORES arv.h struct noarv { int info; struct noarv * esq; struct noarv * dir; }; typedef struct noarv NoArv;

- UNIVERSIDADE DO VALE DO RIO DOS SINOS CENTRO DE CIÊNCIAS EXATAS E TECNOLÓGICAS (C6/6) Curso: Informática

INF 1010 Estruturas de Dados Avançadas

Algoritmos e Estrutura de Dados II

Introdução a Computação

ÁRVORES BINÁRIAS DE PESQUISA

Fundamentos de Programação

Transcrição:

Tópicos Avançados em Estrutura de Dados 6º Período Ciência da Computação Uma Aplicação de Árvores Binárias Árvores Binárias - continuação As árvore binárias são estruturas importantes toda vez que uma decisão binária deve ser tomada em algum ponto de um algoritmo. Vamos agora, antes de passar a algoritmos mais complexos, mostrar uma aplicação simples de árvores binárias. Suponhamos que precisamos descobrir números duplicados em uma lista não ordenada de números. Uma maneira é comparar cada novo número com todos os números já lidos. Isto aumenta em muito a complexidade do algoritmo. Outra possibilidade é manter uma lista ordenada dos números e a cada número lido fazer uma busca na lista. Outra solução é usar uma árvore binária para manter os números. O primeiro número lido é colocado na raiz da árvore. Cada novo número lido é comparado com o elemento raiz, caso seja igual é um valor duplicado e volta-se a ler outro número. Se é menor repete-se o processo com a árvore da direita e se maior com a árvore da esquerda. Este processo continua até que um valor duplicado é encontrado ou uma árvore vazia é achada. Neste caso, o número é inserido na posição devida na árvore. Considere que os números 7 8 2 5 8 3 5 10 4 foram fornecidos pelo usuário, neste caso a árvore binária mostrada na Figura 1 seria construida. Figura 1 O programa abaixo mostra este algoritmo. O programa insere os nós na árvore e imprime uma mensagem caso seja fornecido um número que já foi lido antes. /* programa arv0300.c */ #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 ); int main() tno *raiz, *p, *q; char linha[80], *numero; int num; printf ( Entre com os elementos da lista, separados por espaço: ); gets(linha); numero = strtok(linha, " "); /* pega o primeiro numero da lista */ num = atoi(numero); raiz = cria_arvore(num); /* insere na raiz */ numero = strtok(null, " "); printf("li numero %d\n", num); /* le novo numero */ while(numero) q = raiz; p = raiz; num = atoi(numero); printf("li numero %d\n", num); /* le novo numero */ while (num!= p->info && q) /* procura na arvore */ p = q; if (num < p->info) q = p->esq; /* passa para arvore esquerda */ q = p->dir; /* passa para direita */ if (num == p->info) printf("o numero %d ja existe na arvore.\n", num); /* vou inserir o numero na arvore */ if (num < p->info) pos_esq(p, num); pos_dir(p, num); numero = strtok(null, " "); /* fim do while (numero) */ getch(); return(0); tno *cria_arvore (int x) tno *p; p = cria_no (); if (p) p->info = x; return p; puts("faltou espaco para alocar no."); exit(1); tno *cria_no() tno *p; if ((p = (tno *) malloc(sizeof(tno))) == NULL) return NULL; p->esq = NULL; p->dir = NULL; return p;

void pos_esq(tno *p, int x) tno *q; if (p->esq) puts("operacao de insercao a esquerda ilegal."); 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."); q = cria_arvore(x); p->dir = q; Programa de Percurso - versão recursiva O programa abaixo captura letras informadas pelo teclado e ao final informa o percurso da árvores nos 3 modos: Pré, In e Pós-ordem. // Exemplo de Percuros em Arvores Binarias #include <conio.h> #include <stdio.h> #include <stdlib.h> struct arvore *coloca(struct arvore *atual,char quem,char ld); void construir(struct arvore *filho,char lado,char letra); void mostrar_preordem (arvore *p); void mostrar_inordem (arvore *p); void mostrar_posordem (arvore *p); struct arvore char dado; struct arvore *esq; struct arvore *dir; *Raiz = NULL; main () // Programa Principal char op, letra; construir(raiz,'r',' '); if (Raiz!= NULL) printf("\n\narvore - Pre-Ordem\n");

mostrar_preordem(raiz); printf("\n\narvore - In-Ordem\n"); mostrar_inordem(raiz); printf("\n\narvore - Pos-Ordem\n"); mostrar_posordem(raiz); printf("\a\n\na Arvore esta vazia\n"); getche(); void construir(struct arvore *filho,char lado,char letra) char entra; struct arvore *onde; if (lado == 'r') printf("\ninforme a raiz: "); if (lado == 'e') printf("\ninforme o filho esquerdo de %c: ",letra); printf("\ninforme o filho direito de %c: ",letra); entra = getche(); if (entra!= 13) onde = coloca(filho,entra,lado); construir(onde,'e',entra); construir(onde,'d',entra); struct arvore *coloca(struct arvore *atual,char quem,char ld) struct arvore *alocou; alocou = (struct arvore*) malloc(sizeof(struct arvore)); (*alocou).dado = quem ; (*alocou).esq = NULL; (*alocou).dir = NULL; if (!Raiz) Raiz = alocou ; if (ld == 'e') (*atual).esq = alocou; (*atual).dir = alocou; return alocou; void mostrar_preordem (arvore *p) if (p == NULL) return; printf("%c ",p->dado); mostrar_preordem(p->esq);

mostrar_preordem(p->dir); void mostrar_inordem (arvore *p) if (p == NULL) return; mostrar_inordem(p->esq); printf("%c ",p->dado); mostrar_inordem(p->dir); void mostrar_posordem (arvore *p) if (p == NULL) return; mostrar_posordem(p->esq); mostrar_posordem(p->dir); printf("%c ",p->dado); A seguir, tem-se dois exemplos de entrada e saída de dados referente ao programa :

Programa Catálogo de clientes Uma empresa que produz catálogos telefônicos precisa, a cada ano, inserir novos nomes de assinantes de forma a manter o catálogo classificado em ordem alfabética. Implemente um programa com funções para: Inserir novos nomes de assinantes, e Mostrar a relação de assinantes em ordem alfabética. // prog3.cpp - Exemplo Arvore Binária #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> struct arvore char nome[10]; struct arvore *pai; struct arvore *esq; struct arvore *dir; *Raiz = NULL; void incluir_nome (char novo[]) arvore *p, *q, *r; p = ( arvore *) calloc(1,sizeof( arvore)); strcpy(p->nome,novo); p->esq=null; p->dir=null; if (Raiz == NULL)

Raiz = p; q=raiz; while (q!= NULL) r=q; if (strcmp(novo,q->nome)<= 0) q=q->esq; q=q->dir; if (strcmp(novo,r->nome) <= 0) r->esq=p; r->dir=p; p->pai=r; void mostrar_arvore (arvore *p) if (p == NULL) return; mostrar_arvore(p->esq); printf("\n%s",p->nome); mostrar_arvore(p->dir); main () char op, novo[10]; do printf("nome -> "); fflush(stdin); gets(novo); if (strcmp(novo,"fim") == 0) break; incluir_nome(novo); while (1); printf("relacao de assinantes:\n"); mostrar_arvore(raiz); printf("\n"); getche(); Exemplo de entrada e saída de dados referente ao programa:

ÁRVORES BINÁRIAS DE PESQUISA Um tipo especial de árvore binária é a Árvore Binária de Pesquisa (ABP). Neste tipo de árvores cada nodo tem obrigatoriamente um campo denominado chave que permite impor uma ordenação na árvore que satisfaz a seguinte propriedade. Seja x um nodo numa ABP. Se y é um nodo na subárvore esquerda de x então chave[y] <= chave[x] Se y é um nodo na subárvore direita de x então chave[y] >= chave[x] Exemplos: Figura 2 Observe que o campo chave pode ser qualquer tipo de dado que possa ser ordenado. Outra maneira de guardar essa regra é a seguinte: todos os nós das subárvores da esquerda tem valores da chave menor que o valor da chave raiz e todos os nós das subárvores da direita tem valores da chave maior que o valor da chave raiz. Essa regra é válida recursivamente para todas as subárvores da árvore, ou seja, toda as subárvores da esquerda do nó chave em questão deverão ter valores menores ou iguais e todas as chaves das subárvores da direita deverão ter valores maiores ou iguais. Veja os exemplos das Figura 2 e 3. Figura 3 Exercício: 1) Trace ABP(s) de profundidade 2,3,4,5 e 6 sobre o conjunto de chaves 1,4,5,10,16,17,21 2) Das árvores abaixo, qual(is) está(ão) errada(s) e não pode(m) ser considera(s) com ABP(s)? Justifique sua resposta? G G 15 C J C J 6 18 A F N A H N 3 7 17 20 D G M D G M 2 4 13 (A) (B) (C)

Inserção de informação numa ABP O procedimento de inserção numa ABP deve se encarregar de manter a propriedade de ordenação da árvore, ou seja, a inclusão de uma nova informação deverá encontrar a posição correta para inserção de maneira a não violar a ordenação. Outra particularidade é que não podemos inserir informação com chave duplicada, ou seja, caso a chave associada à informação a ser inserida já existir na árvore ela não é inserida. Algoritmo de inserção: função insere(t,v): //insere um valor v numa arvore T y = null x = raiz[t] enquanto x!= nulo //enquanto x não nulo faça y = x //y recebe x se chave[v] < chave[x] então x = esquerda[x] senão x = direita[x] pai[v] = y se y = nulo então raiz[t] = v //arvore estava vazia senão se chave[v] < chave[y] então esquerda[y] = v senão direita[y] = v Pesquisa numa ABP Para encontrarmos se uma determinada informação I está armazenada numa ABP, comparamos o valor da chave da informação com o valor da chave armazenado na raiz da árvore. Se a chave de I é menor sabemos que I só pode estar na subárvore esquerda; se a chave de I é maior, sabemos que I só pode estar na subárvore direita. Algoritmo de busca: função busca(n,v): //n = nó (primeira vez é a raiz), v = valor a pesquisar se n = nulo ou v = chave[n] então retorna n se v < chave[n] então retorna busca(esquerda[n],v) senão retorna busca(direita[n],v) Removendo informação de uma ABP Esta é uma operação que apresenta certa dificuldade, pois pode ser necessário, em alguns casos, efetuar uma reestruturação de grande parte da árvore. Devemos considerar dois casos distintos: O nodo a ser removido possui uma ou ambas as subárvores vazias. Neste caso a remoção é simples. Se ambas as subárvores são vazias o nodo é simplesmente removido. Se apenas uma delas não é vazia, fazemos a raiz do nodo sendo removido ser a nova raiz da subárvore não vazia. Veja as ilustrações abaixo:

Figura 4 Nenhuma das subárvores do nodo é vazia. Uma solução simples é remover o nodo que contém a chave seguinte na ordem para a qual a árvore está organizada e reinseri-lo no lugar do nodo que se deseja realmente remover. O nodo que contém o símbolo seguinte é aquele que contém a menor chave da subárvore da direita. Veja o exemplo abaixo: Figura 5 Algoritmo de remoção função remove(y): //recebe a árvore cuja raiz deseja excluir e retorna a árvore resultante se esquerda[y] = nulo então c = direita[y] senão c = esquerda[y] enquanto direita[c]!= nulo faça c = direita[c] //c é a célula anterior a y na ordem e-r-d fimenquanto a = pai[c] se a!= y então b = esquerda[c] direita[a] = b pai[b] = a esquerda[c] = esquerda[y] pai[esquerda[y]] = c fimse direita[c] = direita[y] pai[direita[y]] = c fimse pai[c] = nulo retorna c

Exercício: 3) Trace uma ABP com o conjunto de chaves 10,30,1,12,45,2 e depois demonstre como fica essa mesma ABP removendo a chave 30. 4) A partir da ABP que é data em pré-ordem pelas chaves 4,1,10,5,17,16,21, trace a nova ABP com a exclusão das chaves 10 e 21. 5) Trace a nova ABP a partir da remoção da chave 12 da ABP ao lado. Referências Bibliográficas: Algoritmos e Estruturas de Dados III UPF: http://www.eduardostefani.eti.br/bennett/algoritmos2/algoritmos-estrutura-dados.pdf WALTER,Marcelo: http://www.inf.unisinos.br/~marcelow/ensino/grad/lab2/ PIMENTEL, Graça: http://www.icmc.sc.usp.br/~sce182/arvbinrb.html CORMEN, Thomas H. et al. Algoritmos: teoria e prática. Rio de Janeiro: Campus, 2002. TENEMBAUM, Aeron. Estruturas de Dados usando C. São Paulo: Makron Books, 1995. Árvores Binárias PUC PR: http://www.ppgia.pucpr.br/~laplima/aulas/materia/arvbin.html CRUZ, Adriano. Árvores. 2000. http://equipe.nce.ufrj.br/adriano/c/apostila/arvore.htm MINETTO, Elton Luis. Apostila de Árvores Binárias. Unochapecó, 2005