220 likes | 348 Views
Algorítmos e estrutura de dados III. Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação. Árvores de busca binária. Problemas. Se um vetor tiver ordenado é possível obter um algoritmo de pesquisa muito eficiente denominado pesquisa binária
E N D
Algorítmos e estrutura de dados III Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação
Problemas... • Se um vetor tiver ordenado é possível obter um algoritmo de pesquisa muito eficiente denominado pesquisa binária • Não é eficiente na inserção e remoção devido a necessidade de reorganização para manter a ordenação • As listas ligadas resolvem esse problema com o uso de ponteiros • Problema é que algoritmos de pesquisa são sequenciais • Árvore binária resolve esse tipo de problema de forma eficiente
Uma árvore de pesquisa binária é uma árvore binária armazenando chaves (ou itens) em seus nós internos e satisfazendo a seguinte propriedade: Seja u, v e w três nós tais que u é nó esquerdo de v e w é o nó direito. Temos key(u) key(v) key(w) Nós externos não armazenam itens (null) 6 2 9 1 4 8 Árvore de pesquisa binária Itens da esqueda menor que a raiz Itens da direita maior ou igual a raiz Cada subarvore é uma arvore Uma travessia em ordem visita as chaves em ordem crescente
Árvore binária onde os elementos são organizados de forma que: Árvore de pesquisa binária x y < x z > x
Árvore de pesquisa binária 2 9 1 3 3 7 1 5 5 2 8 6 7
Exemplo: 50, 20, 39, 8, 79, 26, 58, 15, 88, 4, 85, 96, 71, 42, 53. 50 20 79 8 39 88 58 4 15 26 42 53 71 85 96 Árvore de pesquisa binária
Estrutura de dados dinâmica, com recuperação em tempo logarítmico. Árvore de pesquisa binária 1 2 3 4
Representação de um Nó struct arvore{ char info; struct arvore *esq, *dir; }; typedef struct arvore *arvorePTR; Uma árvore binária de busca vazia é representada por uma variável ponteiro com conteúdo nulo
Inserindo um elemento em uma árvore de busca binária 5 14 (a) Árvore depois da inserção de 5 e 14
Inserindo um elemento em uma árvore de busca binária 5 14 8 (b) Árvore depois da inserção de 8
Inserindo um elemento em uma árvore de busca binária 5 2 14 8 (c) Árvore depois da inserção de 2
Inserindo um elemento em uma árvore de busca binária 5 2 14 8 20 (d) Árvore depois da inserção de 20
Exemplo: 50, 20, 39, 8, 79, 26, 58, 15, 88, 4, 85, 96, 71, 42, 53. 50 20 79 8 39 88 58 4 15 26 42 53 71 85 96 Inserindo um elemento em uma árvore de busca binária
Inserindo um elemento em uma árvore de busca binária void tInsere (arvorePTR *plist, char x) { if((*plist) == NULL){ *plist=(arvorePTR) malloc (sizeof(struct arvore)); (*plist)->info=x; (*plist)->esq=NULL; (*plist)->dir=NULL; } else{ if (x<(*plist)->info){ tInsere (&((*plist)->esq),x); } else{ tInsere (&((*plist)->dir),x); } }
Pesquisa de um elemento • Se T é uma árvore nula, não há o que pesquisar; • Se a raiz de T armazena o elemento x, a solução é imediata; • Se x é menor que o valor da raiz de T, a busca prossegue na subarvore esquerda de T; • Se x é maior ou igual a T, a busca prossegue na subarvore direita de T
Pesquisa de um elemento AVRPTR aPesq(arvorePTR *plist, char x) { if (*plist == NULL) /*elemento não encontrado*/ return (NULL); else if (x==(*plist)->info) /*elemento encontrado na raiz*/ return (*plist); else if (x<(*plist)->info) /*procura-o numa subarvore*/ return(aPesq(&((*plist)->esq),x)); else return(aPesq(&((*plist)->dir),x)); }
Remoção de um Elemento Três cenários: • Se a Raiz não possuí filhos, a solução é imediata. Podemos removê-la e anular T; • Se a raiz possuí um único filho, podemos remover o nó raiz e o nó filho toma o seu lugar; • Se a raiz possuir dois filhos, não é possível que ambos assumam o lugar do pai. • Qual das subarvores deve assumir o lugar do nó pai removido? • O que deve ser feito com a subarvore que não foi escolhida? • Seu nó ficará órfão?
Remoção de um Elemento • Não pode produzir nós órfãos; • Aplicação pode inserir nós com a mesma “info” (definição de árvore binária): • Impossibilidade de existir em uma subarvore da esquerda elementos maiores ou iguais à raiz; • Subarvore da direita não pode existir nenhum elemento menor que a raiz; • Assim: • Se identificarmos o maior elemento da subarvore da esquerda e o posicionarmos na raiz, a árvore obtida continua seguindo a definição de árvore binária; • O maior elemento em uma árvore binária ordenada encontra-se no nó que ocupa a posição mais à direita; • com certeza esse nó não possuirá um filho à direita; • Mas poderá possuir um filho a esquerda ….
Remoção de um Elemento • Detalhando uma solução: • Elaborar uma função auxiliar; • recebe um ponteiro para uma árvore não nula; • Faz uma pesquisa para identificar o nó que armazena o seu maior elemento; • Retorna o endereço deste nó; ARVPTR tMaior(TREEPTR *plist){TREEPTR t;t=*plist; if (t->dir == NULL){ *plist = (*plist)->esq; return (t); }else return(tMaior(&((*plist)->dir))); }
Remoção de um Elemento • Possíveis passos para remover um nó que tenha dois filhos: p=tMaior(&(t->esq)); /*desliga o nó com o maior valor */ t->info = p->info; /*armazena o valor na raiz da árvore */ free(p); /*libera o nó removido */