Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Árvores Geradoras em Grafos: Definição, Propriedades e Algoritmos, Resumos de Estruturas Discretas e Teoria dos Grafos

Saiba como identificar e construir árvores geradoras em grafos, incluindo árvores geradoras valoradas e as propriedades de árvores binárias. Aprenda a definição recursiva de árvores, os conceitos básicos de nível, grau de saída e ancestrais, e como construir árvores geradoras adicionando arestas sucessivamente.

Tipologia: Resumos

2022

Compartilhado em 24/10/2022

victor-csa
victor-csa 🇧🇷

2 documentos

1 / 22

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
Conceitos básicos
Árvores são um tipo de grafo caracterizado por: Não possuir ciclos (grafo acíclico); Conexo: existe um
caminho entre qualquer par de vértices distinto; Em geral, escolhe-se um vértice para ser a raiz da
árvore.
Árvore geradora em grafos
Uma árvore T é denominada árvore geradora de um grafo conexo G se T é um subgrafo de G e
contém todos os vértices de G
Floresta Geradora
Se um grafo é desconexo, não podemos identificar nenhuma árvore geradora, mas podemos
identificar no mínimo uma floresta de árvores geradoras, uma para cada componente do grafo.
Exemplo de aplicação de árvores geradora:
A figura abaixo ilustra um conjunto de terras separadas por muros. Supondo
que todas são cheias de água, como podemos esvaziar todas, furando um
número mínimo de buracos nos muros?
Uma árvore geradora é a solução
Algoritmo para achar a árvore geradora
Se G não contém ciclos ele já é sua própria árvore geradora; Suponha agora que ele contém um ciclo.
Tirando uma aresta desse ciclo resulta em um grafo ainda conexo; Repita a etapa anterior até que
não exista nenhum ciclo. O grafo obtido é um grafo conexo que é uma árvore; No entanto, esse
algoritmo não é eficiente.
Em vez de construir a árvore geradora removendo arestas do grafo, podemos construí-las
adicionando arestas sucessivamente. Podemos fazer isso de duas maneiras: Busca em profundidade
ou Busca em largura.
Árvore geradora com busca em profundidade
1. Escolha um nó do grafo para ser a raiz da árvore.
2. Construa um caminho começando por esse nó, adicionando arestas sucessivamente, onde cada
nova aresta é incidente com o último nó do caminho e com um nó ainda não pertencente ao
caminho.
3. Continue adicionando arestas a esse caminho para ir o mais longe possível
4. Se o caminho possui todos os nós do grafo, então o caminho é a árvore geradora do grafo
5. Caso contrário, retorne ao nó mais próximo de maneira que um novo caminho possa ser
construído a partir desse nó e que contenha nós ainda não visitados.
Árvore geradora com busca em largura
1.Arbitrariamente escolha um nó do grafo para ser a raiz
2.Adicione todas as arestas incidentes a esse nó
3.Os novos nós adicionados se tornam os nós de nível 1 da árvore geradora
4.Ordene os nós de nível 1
5.Seguindo essa ordem, acrescente cada aresta incidente com os nós do nível, desde que não forme
ciclos
6.Ordene os nós filhos do nível 1, obtendo o nível 2
7.Repita o processo para nível 2 e assim por diante até incluir todos os nós na árvore
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16

Pré-visualização parcial do texto

Baixe Árvores Geradoras em Grafos: Definição, Propriedades e Algoritmos e outras Resumos em PDF para Estruturas Discretas e Teoria dos Grafos, somente na Docsity!

Conceitos básicos Árvores são um tipo de grafo caracterizado por: Não possuir ciclos (grafo acíclico); Conexo: existe um caminho entre qualquer par de vértices distinto; Em geral, escolhe-se um vértice para ser a raiz da árvore. Árvore geradora em grafos Uma árvore T é denominada árvore geradora de um grafo conexo G se T é um subgrafo de G e contém todos os vértices de G Floresta Geradora Se um grafo é desconexo, não podemos identificar nenhuma árvore geradora, mas podemos identificar no mínimo uma floresta de árvores geradoras, uma para cada componente do grafo. Exemplo de aplicação de árvores geradora: A figura abaixo ilustra um conjunto de terras separadas por muros. Supondo que todas são cheias de água, como podemos esvaziar todas, furando um número mínimo de buracos nos muros? Uma árvore geradora é a solução Algoritmo para achar a árvore geradora Se G não contém ciclos ele já é sua própria árvore geradora; Suponha agora que ele contém um ciclo. Tirando uma aresta desse ciclo resulta em um grafo ainda conexo; Repita a etapa anterior até que não exista nenhum ciclo. O grafo obtido é um grafo conexo que é uma árvore; No entanto, esse algoritmo não é eficiente. Em vez de construir a árvore geradora removendo arestas do grafo, podemos construí-las adicionando arestas sucessivamente. Podemos fazer isso de duas maneiras: Busca em profundidade ou Busca em largura. Árvore geradora com busca em profundidade

  1. Escolha um nó do grafo para ser a raiz da árvore.
  2. Construa um caminho começando por esse nó, adicionando arestas sucessivamente, onde cada nova aresta é incidente com o último nó do caminho e com um nó ainda não pertencente ao caminho.
  3. Continue adicionando arestas a esse caminho para ir o mais longe possível
  4. Se o caminho possui todos os nós do grafo, então o caminho é a árvore geradora do grafo
  5. Caso contrário, retorne ao nó mais próximo de maneira que um novo caminho possa ser construído a partir desse nó e que contenha nós ainda não visitados. Árvore geradora com busca em largura 1.Arbitrariamente escolha um nó do grafo para ser a raiz 2.Adicione todas as arestas incidentes a esse nó 3.Os novos nós adicionados se tornam os nós de nível 1 da árvore geradora 4.Ordene os nós de nível 1 5.Seguindo essa ordem, acrescente cada aresta incidente com os nós do nível, desde que não forme ciclos 6.Ordene os nós filhos do nível 1, obtendo o nível 2 7.Repita o processo para nível 2 e assim por diante até incluir todos os nós na árvore

Árvores geradoras em um grafo valorado O peso de uma árvore geradora de G é definido como a soma dos valores de todas as arestas de T. Diferentes árvores geradoras de T podem ter diferentes pesos. Árvore geradora mínima: árvore geradora de G de menor peso. Árvore geradora mínima Aplicações: Em problemas de interligação (comunicação, redes de luz, esgotos, etc.); Em problemas de construção de redes de menor custo (malhas rodoviárias, redes de computadores) Teorema: Uma árvore geradora T de um grafo conexo valorado G é mínima SE E SOMENTE SE não existe qualquer outra árvore geradora de G, a uma distância 1 de T, cujo peso é menor que o peso de T. Distância entre Ti e Tj de G: número de arestas de G presentes em Ti mas não presentes em Tj. Algoritmo de Prim Empregado para encontrar uma árvore geradora mínima em um grafo conexo com pesos Exemplo do algoritmo: Algoritmo de Kruskal Empregado para encontrar uma árvore geradora mínima Árvores: Conceitos básicos Diversas aplicações necessitam de estruturas que representem uma organização hierárquica dos dados. Árvores são estruturas de dados adequadas para a representação hierárquica. A forma mais natural de definir uma estrutura de árvore é a recursividade. Inúmeros problemas podem ser modelados através de árvores. Árvores admitem tratamento computacional eficiente quando comparadas às estruturas mais genéricas como os grafos (os quais por sua vez são mais flexíveis e complexos).

Conceitos básicos - continuação de árvores e árvores binárias •Nível (ou profundidade) e altura de um nó: O nível ou profundidade de um nó é o número de nós do caminho da raiz até o nó. O nível da raiz é, portanto, 0. A altura de um nó v é o número de nós no maior caminho de v até um de seus descendentes. •Nível da raiz (profundidade) e altura de uma árvore: As folhas têm altura 0. O nível da raiz é 0. A altura de uma árvore T é igual ao máximo nível de seus nós. Representa-se a altura de T por h(T) e a altura da sub-árvore de raiz v por h(v). •Grau de um nó: é o número de sub-árvores do nó. •Grau de uma árvore: é o máximo grau dos nós na árvore. •Folhas de uma árvore: são os nós de grau zero. •Filhos de um nó X: são as raízes das sub-árvores do nó X. Neste caso X é o Pai de seus filhos. •Nível de um nó: a raiz da árvore é dita estar no nível zero, se um nó está no nível k , seus filhos estão no nível k+1 (número de linhas). •Altura ou profundidade de uma árvore: é o nível máximo dos nós na árvore. •Ancestrais de um nó: são todos nós ao longo do caminho a partir da raiz até o nó. •Floresta: conjunto de árvores disjuntas. Nomenclaturas: “A” é o pai de “B”, “C” e “D” / “B”, “C” e “D” são filhos de “A” / “B”, “C” e “D” são irmãos / “A” é um ancestral de “G” / “G” é um descendente de “A” / “B”, “D”, “F” e “G” são nós folhas / “A”, “C” e “E” são nós internos. / O grau do nó “A” é 3. / O comprimento do caminho entre “C” e “G” é 2 / O nível de “A” é 0 e o de “G” é 3. / A altura da árvore é 3 Árvore ordenada Uma árvore é dita ordenada quando as subárvores de cada nó formam um conjunto ordenado (assume-se ordenação da esquerda para a direita. Árvores isomorfas Duas árvores não ordenadas são isomorfas quando puderem se tornar coincidentes através de uma permutação na ordem das subárvores de seus nós. Duas árvores ordenadas são isomorfas quando forem coincidentes segundo a ordenação existente entre seus nós. Pode-se definir o conceito de árvores isomorfas quando elas têm a mesma relação de incidência entre nós, mas são desenhadas de forma diferente, isto é, são distintas quando consideradas como árvores ordenadas Árvore Cheia Árvore com número máximo de nós. Uma árvore de grau d tem número máximo de nós se cada nó, com exceção das folhas tem grau d.

Árvore Binária Uma árvore binária T é um conjunto finito de n nós ou vértices, tais que:

  • se T é um conjunto vazio, ou seja, n=0, a árvore é nula, ou vazia, ou •existe um nó especial, r, chamado raiz da árvore •os demais nós constituem um conjunto vazio ou são particionados em dois conjuntos disjuntos, Ter e Tdr, chamadas respectivamente subárvore esquerda e subárvore direita de r •cada subárvore, por sua vez, também é uma árvore binária •as raízes das subárvores esquerda e direita de v, se existirem, são chamadas respectivamente de filho esquerdo e filho direito de v Note que uma árvore binária não é um caso particular de árvore, é um conceito diferente. Podemos dizer que toda árvore binária é uma árvore, mas nem toda árvore é uma árvore binária, mesmo quando cada nó possua grau no máximo 2 (pois os filhos não são denominados filho da esquerda e filho da direita). Propriedades •O número máximo de nós no nível i de uma árvore binária é 2i •O número máximo de nós em uma árvore binária de altura k é 2k+1- •Para qualquer árvore binária, se n 0 é o número de folhas e n 2 é o número de nós de grau 2, então n0=n 2 +1. Número de subárvores vazias Se uma árvore binária tem n > 0 nós, então ela possui n +1 subárvores vazias. Para ver isso, observe que: •Uma árvore com um só nó tem 2 subárvores vazias. •Sempre que “penduramos” um novo nó numa árvore, o número de nós cresce de 1 e o de subárvores vazias também cresce de 1 Tipos especiais de árvores binárias •Uma árvore binária é estritamente binária se todos os seus nós têm 0 ou 2 filhos •Uma árvore binária completa é aquela em que todas as subárvores vazias são filhas de nós do último ou penúltimo nível •Uma árvore binária cheia é aquela em que todas as subárvores vazias são filhas de nós do último nível estritamente binária binária completa binária cheia Representação da árvore binária •Uma árvore binária de altura k é dita cheia se ela possui 2k+1-1 nós.

Representação Encadeada da árvore binária A representação implícita é apropriada quando estamos trabalhando com árvores binárias completas, mas as operações de inserção e remoção de nós no meio da árvore exige um custo computacional elevado. •A implementação com vetores é simples porém tende a desperdiçar memória, e é pouco flexível quando se quer alterar a árvore (inserção e exclusão de nós). •Este custo computacional pode ser reduzido se utilizarmos uma representação encadeada para árvores binárias. Via-de-regra, árvores são implementadas com ponteiros: •Cada nó X contém 3 campos:

  • X.Val : valor armazenado no nó
  • X.Esq : Ponteiro p/ árvore esquerda
  • X.Dir : Ponteiro p/ árvore direita •Uma árvore é representada por um ponteiro para seu nó raiz Definição da estrutura de dados árvore binária TAD Árvore binária - Implementação em C •Implementação das funções: •implementação em geral recursiva •usa a definição recursiva da estrutura •Uma árvore binária é: •uma árvore vazia; ou •um nó raiz com duas sub-árvores: •a sub-árvore da direita (sad) •a sub-árvore da esquerda (sae) Representação da expressão aritmética: (a + (b * (c / d) - e))

Representação Encadeada da árvore binária (parte 2) Um nó será formado por um registro composto de: Campo de informação, Ponteiro para nó esquerdo e Ponteiro para nó direito. Exemplo: usando as operações inicializa e cria, crie uma estrutura que represente a seguinte árvore ao lado. X (info armazenada em cada nó) será considerado como sendo do tipo caracter. Vale a pena notar que a definição de árvore, por ser recursiva, não faz distinção entre árvores e subárvores. Assim, arv_cria pode ser usada para acrescentar (“enxertar”) uma sub-árvore em um ramo de uma árvore, e arv_libera pode ser usada para remover (“podar”) uma sub-árvore qualquer de uma árvore dada.

Travessia em Pré-Ordem (VLR) se árvore vazia; fim visitar o nó raiz percorrer em pré-ordem a sub-árvore esquerda percorrer em pré-ordem a sub-árvore direita •ABDCEGFHI •visita o nó quando passar a sua esquerda •notação pré-fix Travessia em In-Ordem (LVR) se árvore vazia, fim percorrer em in-ordem a sub-árvore esquerda visitar o nó raiz percorrer em in-ordem a sub-árvore direita •DBAEGCHFI •visita o nó quando passar embaixo do nó •notação in-fix Travessia em Pós-Ordem (LRV) se árvore vazia, fim percorrer em Pós-Ordem a sub-árvore esquerda percorrer em Pós-Ordem a sub-árvore direita visitar o nó raiz •DBGEHIFCA •visita o nó quando passar a sua direita •notação pós-fix Algoritmos de travessia em árvores binárias Observe que os procedimentos são recursivos, devido à natureza recursiva da estrutura (árvore).

Percurso em extensão ou largura Corresponde a visitar cada nó começando o nível mais baixo (ou mais alto) e movendo para baixo (ou para cima) nível a nível, visitando nós em cada nível da esquerda para direita (ou da direita para a esquerda). Árvores binárias de busca (BST) Árvore binária de busca (BST): é uma árvore binária onde, o campo chave de cada nó é:

  1. Maior ou igual à chave de todos os elementos da sub-árvore esquerda, ou seja , os elementos da subárvore são menores que o elemento armazenado em x
  2. Menor ou igual à chave de todos os elementos da sub-árvore direita de x, ou seja, os elementos da subárvore são maiores que o referido elemento Ao realizar um percurso in-ordem em uma árvores binária de busca obtém-se os dados de forma ordenada: 1 2 3 4 5 6 8 10 11 12 13 14 15 Verificar se um dado valor x existe em uma árvore binária de busca: A busca começa pelo nó raiz. Quando a busca chega a um nó qualquer da árvore, ou esse nó já contém o valor procurado e a busca terminar, ou ele contém um valor menor ou maior que x. Isso orienta o prosseguimento da busca em apenas uma das subárvores, podendo descartar a outra subárvore. Algoritmo de busca // Recebe uma árvore de busca r e um número k. Devolve um nó // cuja chave é k; se tal nó não existe, devolve NULL. noh * busca (arv *r, int k) { if (r == NULL || r->chave == k) return r; if (r->chave > k) return busca (r->fesq, k); else return busca (r->fdir, k); } Complexidade da busca em uma árvore binária de busca A complexidade do pior caso é igual à altura da árvore. O pior caso pode ser O(n), onde n é o número de nós da árvore. Quando a árvore está balanceada, a busca é eficiente e o pior caso é O(log n). Veremos o caso médio mais tarde.

•A origem da denominação AVL vem dos seus dois criadores: A del’son- V el’skii e L andis. •Ano de divulgação: 1962. TAD - árvore AVL Árvore AVL •Uma árvore binária balanceada é aquela na qual, para cada nó, as alturas de suas sub-árvores esquerda e direita diferem de, no máximo, 1. •Fator de balanceamento (FB) de um nó é a diferença entre a altura da subárvore esquerda em relação à sub-árvore direita. FB(p) = altura(sub-árvore esquerda de p) - altura(sub-árvore direita de p) •Em uma árvore binária balanceada todos os

FB de todos os nós estão no intervalo -1 ≤ FB

•Inicialmente inserimos um novo nó na árvore normalmente. •A inserção deste pode degenerar a árvore. •A restauração do balanceamento é feita através de rotações na árvore no nó “pivô”. •Nó “pivô” é aquele que após a inserção possui Fator de Balanceamento fora do intervalo. •Primeiro caso: (rotação simples para a direita) •FB > 1 (subárvore esquerda maior que subárvore direita) •E a subárvore esquerda desta subárvore esquerda é maior que a subárvore direita dela •Então realizar uma rotação simples para a direita. •Segundo caso: (rotação simples para a esquerda) •FB < -1 (subárvore esquerda menor que subárvore direita) •E a subárvore direita desta subárvore direita é maior que a subárvore esquerda dela •Então realizar uma rotação simples para a esquerda.

•Terceiro caso: (rotação dupla para a direita) •FB > 1 (subárvore esquerda maior que subárvore direita) •E a subárvore esquerda desta subárvore esquerda é menor ou igual que a subárvore direita dela •Então realizar uma rotação dupla para a direita. •Quarto caso: (rotação dupla para a esquerda) •FB < -1 (subárvore esquerda menor que subárvore direita) •E a subárvore direita desta subárvore direita é menor que a subárvore esquerda dela •Então realizar uma rotação dupla para a esquerda.

Tempos de execução para Árvore AVL •uma única reestruturação é O(1) •usando uma árvore binária implementada •com estrutura ligada •pesquisa é O(log n) •altura de árvore é O(log n), não necessita reestruturação •inserir é O(log n) •busca inicial é O(log n) •reestruturação para manter balanceamento é O(log n) •remove é O(log n) •busca inicial é O(log n) •reestruturação para manter balanceamento é O(log n) Para que servem as Árvores Binárias? Exemplos de aplicações: •Redes de Comunicação de Dados Envio de pacotes ordenados e/ou redundantes •Codificação de Huffman Compressão e Descompressão de arquivos —----------------------------------------------------------------------------------------------------------------------------------- O que são árvores Rubro-negras •Inventadas por Rudolf Bayer. Inventou a árvore-B e red-black •Árvores de pesquisa binária com um bit de informação adicional: a sua cor. •Pode ser rubra ou negra •Limitação da coração dos nodos da raiz às folhas •Garante que nenhum caminho é mais que duas vezes mais longo que qualquer outro •Árvore semibalanceada •Propriedades comuns a Árvores-B de ordem 4 Propriedades 1.Todo nodo ou é rubro ou é negro

  1. A raiz é negra
  2. Toda folha é negra °Folhas são somente os nodos vazios (ponteiros nulos). 4.Se um nodo for rubro, então ambos os filhos são negros. 5.Para todo nodo, todos os caminhos até uma folha contém o mesmo número de nodos negros. Implementação rubro-negra •Nodo possui dois campos a mais: pai e cor Classe nodoRB { info : tipo_info; esq : *nodoRB; dir : *nodoRB; pai : *nodoRB; cor : {rubro, negro}; }; •Folhas nulas obrigatórias (“toda folha é negra”) °Pode-se empregar um único nodo sentinela para representar todas as folhas •Para fins de visualização em nossos algoritmos vamos ignorar as folhas

Rotações Rubro-negras •Árvores Rubro-Negras também realizam rotações para efetuar ajustes •O Procedimento é quase idêntico à rotação simples das árvores AVL •Mudam os nomes dos algoritmos •Rotação simples à esquerda passa a se chamar rotação para a direita •Rotação simples à direita passa a se chamar rotação para a esquerda Inserções Rubro-negras •A inclusão é sempre executada utilizando-se o algoritmo de inserção em árvore de busca •Modificado para manter os ponteiros para o pai. •Todo novo nodo é colorido rubro. •Sempre ganha duas folhas nulas negras •Se o pai do novo nodo for negro •Está pronto, trata-se de uma árvore-RB(rubor negra) •Se o pai for rubro •A propriedade 4 está ferida •Até duas rotações devem ser realizadas Ajustes Rubro-negros •Para todo nodo v definimos uma vizinhança-RB

  • v, seu pai, seu avô e seu tio (RB é binária, haverá no máximo 1 tio) •Um passo-CE de correção-ou-elevação envolve : recolorir e (eventualmente) rotacionar a vizinhança-RB •Um passo-CE provoca : a restituição da propriedade 4 ou a elevação do erro para um nível acima na árvore-RB

Caso 2ed (esquerda-direita)

  • v é um filho da esquerda, cujo pai é um filho rubro da direita e cujo tio é negro
  • rotacionamos para a direita v e seu pai °atualizamos o nodo corrente °caímos no caso 3

Caso 3d (direita)

  • v é um filho da direita, cujo pai é um filho rubro da direita e cujo tio é negro •rotacionamos para a esquerda entre o avô e o pai •recorimos o pai e o avô °pai fica negro °avô fica rubro