A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

INE5408 Estruturas de Dados Árvores Binárias de Busca - Características - Algoritmos - Inserção, deleção e pesquisa.

Apresentações semelhantes


Apresentação em tema: "INE5408 Estruturas de Dados Árvores Binárias de Busca - Características - Algoritmos - Inserção, deleção e pesquisa."— Transcrição da apresentação:

1

2 INE5408 Estruturas de Dados Árvores Binárias de Busca - Características - Algoritmos - Inserção, deleção e pesquisa

3 Introdução Árvores (binárias) são muito utilizadas para se representar um grande conjunto de dados onde se deseja encontrar um elemento de acordo com a sua chave. Definição - Árvore Binária de Busca (Niklaus Wirth): “Uma árvore que se encontra organizada de tal forma que, para cada nodo t i, todas as chaves (info) da subárvore à esquerda de t i são menores que (ou iguais a) t i e à direita são maiores que t i ”. Termo em Inglês: Search Tree.

4 Características Em uma árvore binária de busca é possível encontrar-se qualquer chave existente descendo-se pela árvore: –sempre à esquerda toda vez que a chave procurada for menor do que a chave do nodo visitado; –sempre à direita toda vez que for maior.

5 Características A escolha da direção de busca só depende da chave que se procura e da chave que o nodo atual possui. A busca de um elemento em uma árvore balanceada com n elementos toma tempo médio < log(n), sendo a busca então O(log n). Graças à estrutura de árvore a busca poderá ser feita com apenas log(n) comparações de elementos.

6 Exemplo de árvore binária de busca 8 5 26 713 15 1119 21913

7 Algoritmo de busca tNodo* FUNÇÃO busca (chave: tInfo, ptr: *tNodo) início enquanto (ptr ~= NULO E ptr->info ~= chave) faça // Esquerda ou direita. se (ptr->info < chave) então ptr filhoÀDireita senão ptr filhoÀEsquerda; fim se fim enquanto retorne ptr; fim

8 Algoritmo de inserção tNodo* FUNÇÃO inserção (raiz: *tNodo, info: tInfo) oNovo: *tNodo; início se (info info) então // Inserção à esquerda. se (raiz->filhoÀEsquerda = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀEsquerda <- oNovo; senão raiz filhoÀEsquerda, info); fim se senão // Inserção à direita. se (raiz->filhoÀDireita = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀDireita <- oNovo; senão raiz filhoÀDireita, info); fim se fim

9 Algoritmo de inserção tNodo* FUNÇÃO inserção (raiz: *tNodo, info: tInfo) oNovo: *tNodo; início se (info info) então // Inserção à esquerda. se (raiz->filhoÀEsquerda = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀEsquerda <- oNovo; senão raiz filhoÀEsquerda, info); fim se senão // Inserção à direita. se (raiz->filhoÀDireita = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀDireita <- oNovo; senão raiz filhoÀDireita, info); fim se fim

10 Algoritmo de inserção tNodo* FUNÇÃO inserção (raiz: *tNodo, info: tInfo) oNovo: *tNodo; início se (info info) então // Inserção à esquerda. se (raiz->filhoÀEsquerda = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀEsquerda <- oNovo; senão raiz filhoÀEsquerda, info); fim se senão // Inserção à direita. se (raiz->filhoÀDireita = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀDireita <- oNovo; senão raiz filhoÀDireita, info); fim se fim

11 Algoritmo de inserção tNodo* FUNÇÃO inserção (raiz: *tNodo, info: tInfo) oNovo: *tNodo; início se (info info) então // Inserção à esquerda. se (raiz->filhoÀEsquerda = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀEsquerda <- oNovo; senão raiz filhoÀEsquerda, info); fim se senão // Inserção à direita. se (raiz->filhoÀDireita = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀDireita <- oNovo; senão raiz filhoÀDireita, info); fim se fim

12 Algoritmo de inserção tNodo* FUNÇÃO inserção (raiz: *tNodo, info: tInfo) oNovo: *tNodo; início se (info info) então // Inserção à esquerda. se (raiz->filhoÀEsquerda = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀEsquerda <- oNovo; senão raiz filhoÀEsquerda, info); fim se senão // Inserção à direita. se (raiz->filhoÀDireita = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀDireita <- oNovo; senão raiz filhoÀDireita, info); fim se fim

13 Algoritmo de inserção tNodo* FUNÇÃO inserção (raiz: *tNodo, info: tInfo) oNovo: *tNodo; início se (info info) então // Inserção à esquerda. se (raiz->filhoÀEsquerda = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀEsquerda <- oNovo; senão raiz filhoÀEsquerda, info); fim se senão // Inserção à direita. se (raiz->filhoÀDireita = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀDireita <- oNovo; senão raiz filhoÀDireita, info); fim se fim

14 Algoritmo de inserção tNodo* FUNÇÃO inserção (raiz: *tNodo, info: tInfo) oNovo: *tNodo; início se (info info) então // Inserção à esquerda. se (raiz->filhoÀEsquerda = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀEsquerda <- oNovo; senão raiz filhoÀEsquerda, info); fim se senão // Inserção à direita. se (raiz->filhoÀDireita = NULO) então oNovo <- aloque(tNodo); oNovo->info <- info; oNovo->filhoÀEsquerda <- NULO; oNovo->filhoÀDireita <- NULO; raiz->filhoÀDireita <- oNovo; senão raiz filhoÀDireita, info); fim se fim

15 Exemplo: inserção de um elemento com chave = 14 8 5 26 713 15 1119 21913 chave = 14 14 > 8

16 Exemplo: inserção de um elemento com chave = 14 8 5 26 713 15 1119 21913 chave = 14 14 > 8 14 < 15

17 Exemplo: inserção de um elemento com chave = 14 8 5 26 713 15 1119 21913 chave = 14 14 > 8 14 < 15 14 > 11

18 Exemplo: inserção de um elemento com chave = 14 8 5 26 713 15 1119 21913 chave = 14 14 > 8 14 < 15 14 > 11 14 > 13

19 Exemplo: inserção de um elemento com chave = 14 8 5 26 713 15 1119 21913 chave = 14 14 > 8 14 < 15 14 > 11 14 > 13 ptr = nulo

20 Exemplo: inserção de um elemento com chave = 14 8 5 26 713 15 1119 21913 chave = 14 14 > 8 14 < 15 14 > 11 14 > 13 14

21 Algoritmo de deleção A deleção é mais complexa do que a inserção. A razão básica é que a característica organizacional da árvore não deve ser quebrada: –a subárvore da direita de um nodo não deve possuir chaves menores do que o pai do nodo eliminado; –a subárvore da esquerda de um nodo não deve possuir chaves maiores do que o pai do nodo eliminado. Para garantir isso, o algoritmo de deleção deve remanejar os nodos.

22 Exemplo: deleção do nodo com chave = 15 8 3 15 6 7 11 9 14 15 12 10 13

23 Exemplo: deleção do nodo com chave = 15 8 3 15 6 7 11 9 14 12 10 13

24 Deleção em uma árvore de busca binária Se o nodo possuir somente uma subárvore filha: –podemos simplesmente mover esta subárvore toda para cima; –o único sucessor do nodo a ser excluído será um dos sucessores diretos do pai do nodo a ser eliminado; –se o nodo a ser excluído é filho esquerdo de seu pai, o seu filho será o novo filho esquerdo deste e vice-versa.

25 Exemplo: deleção do nodo com chave = 5 8 3 15 6 7 11 9 14 15 12 10 13

26 Exemplo: deleção do nodo com chave = 5 8 3 1 6 7 11 9 14 15 12 10 13

27 Exemplo: deleção do nodo com chave = 5 8 3 1 6 7 11 9 14 15 12 10 13

28 Deleção em uma árvore de busca binária Se o nodo possuir duas subárvores filhas: –se o filho à direita não possui subárvore esquerda, é ele quem ocupa o seu lugar; –se possuir uma subárvore esquerda, a raiz desta será movida para cima e assim por diante; –a estratégia geral (Mark Allen Weiss) é sempre substituir a chave retirada pela menor chave da subárvore direita.

29 Exemplo: deleção do nodo com chave = 11 8 3 15 6 7 11 9 14 15 12 10 13

30 Exemplo: deleção do nodo com chave = 11 8 3 15 6 7 11 9 14 15 12 10 13 12

31 Exemplo: deleção do nodo com chave = 11 8 3 15 6 7 12 9 14 15 13 10

32 Algoritmo de deleção tNodo* FUNÇÃO delete(info: tInfo, arv: *tNodo) tmp, filho: *tNodo; início se (arv = NULO) então retorne arv senão se (info info) // Vá à esquerda. arv->filhoÀEsquerda filhoÀEsquerda); retorne arv; senão se (info > arv->info) // Vá à direita. arv->filhoÀDireita filhoÀDireita); retorne arv; senão // Encontrei elemento que quero deletar. (CONTINUA)

33 Algoritmo de deleção (CONTINUAÇÃO) se (arv->filhoÀDireita ~= NULO E arv->filhoÀEsquerda ~= NULO) // 2 filhos. tmp filhoÀDireita); arv->info info; arv->filhoÀDireita info, arv->filhoÀDireita); retorne arv; senão // 1 filho. tmp <- arv; se (arv->filhoÀDireita ~= NULO) então // Filho à direita. filho filhoÀDireita; retorne filho; senão se (arv->filhoÀEsquerda ~= NULO) então // Filho à esquerda. filho filhoÀEsquerda; retorne filho; senão // Folha. libere arv; retorne NULO; fim se fim

34 Problemas com árvores binárias de busca Deterioração: –quando inserimos utilizando a inserção simples, dependendo da distribuição de dados, pode haver deterioração; –árvores deterioradas perdem a característica de eficiência de busca.

35 Problemas com árvores binárias de busca

36 Exemplo: inserção de uma série de nomes parcialmente ordenados em uma árvore binária de busca Alberto Aarão Ana Antonio Beatriz Babette Carlos Claudia Clóvis Cesar Davi Denise Daltro Eva Everson Gerson Giovana Josi Jaci Xisto Xênia Zenaide

37 Alberto Aarão Ana Beatriz Babette Claudia César Davi Daltro Denise Eva Everson Gerson Giovana Clóvis Carlos …e assim por diante...

38 Exercícios Uma árvore é uma estrutura tipicamente recursiva. Nós vimos um algoritmo iterativo para realizar busca. Porque não utilizar um algoritmo recursivo para a busca em uma árvore binária de busca? Elabore um algoritmo recursivo para efetuar uma busca em uma árvore binária de busca pressupondo as estruturas de dados do exemplo anterior. Existe alguma razão para evitarmos algoritmos de busca em árvore recursivos (memória, complexidade, etc)? Justifique.

39 Exercícios O algoritmo recursivo de inserção em árvore binária de busca apresentado é bastante simples e reflete bem a estrutura da própria árvore. Não será possível também realizar a função deste algoritmo com um algoritmo iterativo? Crie um algoritmo iterativo para a inserção simples em uma árvore binária de busca.

40 Exercícios Elimine os nodos 3 e 12 da árvore do exemplo de deleção em árvore binária de busca anterior, nesta ordem, a partir da árvore anterior utilizando o algoritmo dado. Mostre o stack a cada chamada recursiva.

41 Atribuição-Uso Não-Comercial-Compartilhamento pela Licença 2.5 Brasil Você pode: - copiar, distribuir, exibir e executar a obra - criar obras derivadas Sob as seguintes condições: Atribuição — Você deve dar crédito ao autor original, da forma especificada pelo autor ou licenciante. Uso Não-Comercial — Você não pode utilizar esta obra com finalidades comerciais. Compartilhamento pela mesma Licença — Se você alterar, transformar, ou criar outra obra com base nesta, você somente poderá distribuir a obra resultante sob uma licença idêntica a esta. Para ver uma cópia desta licença, visite http://creativecommons.org/licenses/by-nc-sa/2.5/br/ ou mande uma carta para Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.


Carregar ppt "INE5408 Estruturas de Dados Árvores Binárias de Busca - Características - Algoritmos - Inserção, deleção e pesquisa."

Apresentações semelhantes


Anúncios Google