Pilhas
Imagine uma pilha de pratos. Quando se vai lavá-los, você não começa
retirando o que está mais abaixo, e sim o que está no topo da pilha. É
basicamente assim que esse tipo de estrutura de dados funciona.
typedef struct pilha Pilha; //redefinição do tipo struct pilha para simplesmente Pilha
Código:
#define N 50
struct pilha {
int n;
float vet[N];
};
p->vet[p->n] = v;
p->n++;
}
A função de remoção retira um elemento (o que estiver no topo) e retorna
esse elemento, daí o retorno dessa função ser do tipo float, pois esse é o tipo
do dado que estamos armazenando na pilha. Se for um dado de outro tipo
(char, por exemplo), bastaria você alterar o tipo de retorno da função para
char.
Código:
float pilha_remove (Pilha* p)
{
float v;
if (pilha_vazia (p))
{
printf (“Pilha está vazia!\n”);
exit(1);
}
v = p->vet[p->(n-1)];
p->n--;
return v;
}
Pode-se implementar a função que verifica se a pilha está vazia da seguinte
maneira:
Código:
int pilha_vazia (Pilha* p)
{
return (p->n == 0); /*se isto for verdade, será retornado o conteúdo
dos parêntesis, caso contrário será retornado zero. */
}
Filas
typedef struct fila Fila; //redefinição do tipo struct fila para simplesmente Fila
Mais uma vez, para simplificar, vamos implementar uma Fila a partir de um
vetor. Como um vetor em C tem uma quantidade fixa de elementos, digamos,
N elementos, observe que mais uma vez temos um limite na quantidade de
elementos a serem armazenados na fila.
De acordo com a idéia central da fila (FIFO - primeiro a entrar, primeiro a sair), ao
usarmos um vetor para implementação da fila, observe que, quando retiramos
elementos dela, é como se a fila “andasse” no vetor, pois ao se retirar elemento(s) da
fila, o índice do vetor que representa o topo da fila se altera. Por exemplo, imagine
um vetor de N = 6 posições. Se inserirmos 4 elementos, teremos as 4 primeiras
posições da fila ocupadas. Ao retirarmos 2 elementos (lembre-se que serão retirados
os 2 primeiros), temos agora a situação em que o 1º elemento da fila, ou seja, o topo
dela, será representado pelo 3º elemento inicialmente inserido, conforme ilustra a
figura:
Por causa desse fato, precisamos fazer uma alteração nos índices do vetor a cada vez
que realizarmos uma remoção de quaisquer elementos da fila. Essa reordenação é
feita de forma “circular” no vetor, afim de aproveitar as posições liberadas quando se
retira elementos. No exemplo citado, teríamos a seguinte situação ilustrativa, após
essa reordenação:
Essa reordenação de índices pode ser feita utilizando uma função específica:
Código:
Static int incr (int i)
{
return (i+1)%N;
}
Código:
i = (i+1)%N;
Para a interface da fila, Pode-se utilizar uma estrutura contando 3 campos: um vetor
de tamanho N, um inteiro n para representar o número de elementos armazenados
na fila e um índice ini para o início da fila.
Tendo o índice para o início da fila, Pode-se calcular o índice para o final da fila, que
chamaremos de fim da seguinte maneira:
Código:
fim = (ini+n)%N;
Código:
#define N 100
struct fila
{
int n;
int ini;
float vet[N];
}
Código:
Fila* fila_cria (void)
{
Fila* f = (Fila*) malloc(sizeof(Fila));
f->n = 0; //inicializa a fila
vazia;
f->ini = 0; //escolhe uma posição
inicial;
return f;
}
A função que insere elementos na fila deve verificar se existe espaço disponível para
esta inserção, e inserir o elemento no final da fila, utilizando o índice fim, conforme já
falamos anteriormente:
Código:
void fila_insere (Fila* f, float v)
{
int fim;
if (f-> == N)
{
printf (“Fila não tem espaço disponível”);
exit (1);
}
A função para retirar um elemento da fila verifica se a fila já está ou não vazia:
Código:
float fila_retira (Fila* f)
{
float v;
if (fila_vazia(f))
{
printf (“Fila vazia\n”);
exit (1);
}
v = f->vet[f->ini];
f->ini = (f->ini + 1) % N;
f->n--;
return v;
Código:
void fila_libera (Fila* f)
{
free (f);
}
Listas encadeadas
int info;
struct lista* prox;
}
A função que cria uma lista simplesmente encadeada retornará um NULL do tipo da
lista, ou seja, uma lista totalmente vazia:
Código:
Lista* lst_cria (void)
{
return NULL;
}
A função de inserção insere novos elementos no início da lista encadeada, pois esta é
a maneira mais simples de se inserir elementos numa lista, seja ela simplesmente ou
duplamente encadeada. É importante lembrar que uma lista é representada pelo
ponteiro para o primeiro elemento dela todos os demais elementos estão encadeados
um a um sucessivamente, a partir do primeiro. Ou seja, para se acessar qualquer
elemento da lista, basta fornecer o ponteiro para o primeiro elemento e ir
percorrendo elemento a elemento até se chegar no elemento desejado.
Código:
Lista* lst_insere (Lista* l, int i)
{
Lista* novo = (Lista*) malloc (sizeof(Lista));
novo->info = i;
novo->prox = l;
return novo;
}
Observe que o novo elemento é encadeado aos demais já existentes na lista (caso ela
já tenha outros elementos) e a nova lista é representada pelo novo elemento
inserido, que passa a ser o 1º da lista.
Código:
void lst_imprime (Lista* l)
{
Lista*p;
Código:
int lst_vazia (Lista* l)
{
return (l == NULL);
}
Código:
Lista* lst_retira (Lista* l, int v)
{
Lista* ant = NULL;
Lista* p = l;
if (p == NULL)
return l;
if (ant == NULL)
{
l = p->prox;
}
else
{
ant->prox = p->prox;
}
free (p);
return l;
Código:
void lst_libera (Libera* l)
{
Lista* p= l;
while (p != NULL)
{
Lista* t = p->prox;
free (p);
p = t;
}
}
Uma lista duplamente encadeada possui 2 ponteiros em cada Nó, um para o próximo
elemento e outro para o anterior (ant e prox respectivamente). Isso possibilita
“andarmos” para “frente” e para “trás” ao longo da lista.
Código:
struct lista2
{
int info;
struct lista2* ant;
struct lista2* prox;
};
if (l != NULL)
l->ant = novo;
return novo;
}
Função de busca:
Código:
Lista2* lst2_busca (Lista2* l, int v)
{
Lista2* p;
for (p = l; p != NULL; p = p->prox)
if (p->info == v)
return p;
Código:
Lista2* lst2_retira (Lista* l, int v)
{
Lista2* p = busca(l, v); //procura o elemento
if (l == p)
l = p->prox;
else
p->ant->prox = p->ant;
free (p);
return l;
}
Além dessas estruturas, é possível criar muitas outras até mesmo juntando
estruturas diferentes para se formar uma. Por exemplo, você pode implementar uma
pilha ou fila utilizando uma lista encadeada ao invés de um vetor, como fizemos. O
retorno das funções podem ser diferentes, de acordo com a necessidade, e assim por
diante. As estruturas de dados são “maleáveis” e você pode utilizá-las como quiser,
desde que preserve os conceitos fundamentais de cada uma.
Nada do que foi explanado aqui foi copiado de alguém, apenas os códigos das funções
que utilizei de um livro de estruturas de dados, chamado “Introdução a Estruturas de
Dados”, de Waldemar Celes.
__________________
"O importante é ganhar. Tudo e sempre. Essa história que o importante é competir
não passa de demagogia." Senna
Observação (1)
Uma árvore não ordenada simples, conforme este diagrama - o Nó rotulado 7 tem dois Filhos, o
2 e o 6, e um dos Pais, com o 2. O Nó raiz, no topo, não tem Pai.
Em ciência da computação , uma árvore é uma estrutura amplamente utilizada. Esta estrutura
de dados que emula um sistema hierárquico (estrutura de árvore) com um conjunto de Nós
associados.
Terminologia
Um Nó é uma estrutura que pode conter um valor, uma condição, ou representar uma estrutura
de dados separados (o que poderia ser uma árvore de seu próprio). Cada Nó de uma árvore ou
mais Nós Filho zero, que estão abaixo dele na árvore (por convenção, as árvores são extraídas
cresce para baixo). Um Nó que tem um Filho é chamado Filho do Pai do Nó (ou nodo Pai, ou
superior ). Um Nó tem no máximo um Pai.
Nós que não têm Filhos são chamados Nós folhas . Eles também são chamados de Nós
terminais.
A altura de um Nó é o comprimento do caminho mais longo para baixo de uma folha desse Nó.
A altura da raiz é a altura da árvore. A profundidade de um Nó é o comprimento do caminho
para a raiz (ou seja, o caminho de raiz). Isto é comumente necessária na manipulação dos
diferentes árvores auto balanceamento, Árvores AVL , em particular. Convencionalmente, o
valor -1 corresponde a um sub sem Nós, ao passo que zero corresponde a uma subárvore com
um Nó.
O Nó mais alto em uma árvore é chamado Nó raiz. Sendo o Nó superior, o Nó raiz não têm Pais.
É o Nó em que as operações sobre a árvore comumente começar (apesar de alguns algoritmos
de começar com os Nós folha e trabalhar até terminar na raiz). Todos os outros Nós podem ser
alcançados a partir dele, seguindo as bordas ou links. (Na definição formal, cada caminho como
também é único). Nos diagramas, é tipicamente desenhado no topo. Em algumas árvores, tais
como pilhas , o Nó raiz tem propriedades especiais. Cada Nó em uma árvore pode ser visto
como o Nó raiz da subárvore enraizada naquele Nó.
Um Nó interno ou Nó interno é qualquer Nó de uma árvore que Nós Filho , não sendo,
portanto, um Nó folha .
Tree - Representações
Há muitas maneiras diferentes para representar árvores, representações comuns representam a
Nós como registros alocado na heap (para não ser confundida com a estrutura de dados heap )
com ponteiros para seus Filhos, seus Pais, ou ambos, ou de itens em um array , com as relações
entre eles determinada pela sua posição na matriz (por exemplo, heap binário ).
Árvores e gráficos
A árvore de estrutura de dados pode ser generalizada para representar dirigido gráficos ,
eliminando as restrições que um Nó pode ter, no máximo, um Pai, e que não são permitidos
ciclos. As bordas são ainda considerados abstratamente como pares de Nós, no entanto, a mãe
ea criança são termos usualmente substituída pela terminologia diferente (por exemplo, de
origem e destino). Diferentes estratégias de implementação existem, por exemplo, listas de
adjacência .
Em teoria dos grafos , uma árvore é conectado acíclico gráfico , salvo indicação em contrário, as
árvores e os gráficos são sem direção. Não existe uma correspondência um-para-um entre as
árvores e as árvores, tais como estrutura de dados. Pode-se ter uma árvore sem direção
arbitrária, arbitrariamente, escolher um de seus vértices como a raiz, fazer todas as suas arestas,
tornando-os pontos de distância do Nó raiz - produzindo uma arborescência - e atribuir uma
ordem para todos Nós. O resultado corresponde a uma estrutura de dados árvore. Escolher
uma raiz diferente ou ordenação produz um diferente.
MétodoTraversal
Ver artigo principal: o percurso da árvore
Percorrendo os elementos de uma árvore, por meio das ligações entre Pais e Filhos, é chamado
de pé da árvore, ea ação é um pé de árvore. Muitas vezes, uma operação pode ser realizada
quando um ponteiro chega a um Nó particular. Uma caminhada em que cada Nó Pai é
atravessado antes dos seus Filhos é chamada de pré-encomenda a pé, uma caminhada em que
as crianças são percorridos antes de seus respectivos Pais são percorridos é chamado de pós-
ordem a pé, uma caminhada em que deixou subárvore de um Nó , então o próprio Nó, e
finalmente a sua subárvore direita são percorridos é chamado de passagem de fim-in. (Este
último cenário, referindo-se exatamente duas subárvores, uma subárvore esquerda e uma
subárvore direita, assume, especificamente, uma árvore binária ).
Operações comuns
• Enumerando todos os itens
• Enumerando uma seção de uma árvore
• Pesquisando um item
• Adicionando um novo item em uma determinada posição na árvore
• Excluindo um item
• Remover uma seção inteira de uma árvore (chamada poda )
• Adicionando uma seção inteira de uma árvore (chamada de enxertia )
• Encontrando a raiz para qualquer Nó
Usos comuns
Estude também
Outras árvores
• algoritmo DSW
• Tiro
• Árvore binária Esquerda-direita criança irmão
Árvore binária
Uma árvore binária simples de tamanho 9 e 3 de altura, com um Nó raiz cujo valor é de 2. A
árvore acima não é nem classificado nem uma árvore binária balanceada
Em ciência da computação , uma árvore binária é uma árvore de estrutura de dados em que
cada Nó tem no máximo dois Filhos . Normalmente, o primeiro Nó é conhecido como o Pai e os
Nós Filhos são chamados de esquerda e direita.
Na teoria dos tipos , uma árvore binária com os Nós do tipo A é definida indutivamente como T =
A μα. 1 + A × α × α. Árvores binárias são comumente usadas para implementar as árvores de
busca binária e heaps binários .
• Uma aresta direcionada refere-se à ligação da mãe para o Filho (setas na imagem da
árvore).
• O Nó raiz de uma árvore é o Nó sem Pais. Há mais de um Nó raiz de uma árvore
enraizada.
• Um Nó folha não tem Filhos.
• A profundidade de um Nó n é o comprimento do caminho desde a raiz até o Nó. O
conjunto de todos os Nós em uma determinada profundidade é às vezes chamado de um
nível da árvore. O Nó raiz é zero em profundidade (ou uma [1] ).
• A altura de uma árvore é o comprimento do caminho desde a raiz até o mais profundo
Nó na árvore. A raiz) da árvore (com apenas um Nó (a raiz) tem uma altura de zero (ou
um [2] ).
• Os irmãos são os Nós que compartilham o mesmo Nó Pai.
• Se existe um caminho de Nó a Nó p, q, onde p Nó está mais próximo do Nó de raiz do
que q, então p é um antepassado de Q e Q é um descendente de p.
• O tamanho de um Nó é o número de descendentes que tem inclusive em si.
• Em grau de um Nó é o número de arestas que chegam a esse Nó.
• Fora grau de um Nó é o número de arestas que saem do Nó.
• Raiz é o único Nó na árvore com In-degree = 0.
• Um binário é uma árvore enraizada enraizado árvore em que cada Nó tem no máximo
dois Filhos.
• Uma árvore binária completa (às vezes boa árvore binária ou 2-árvore ou árvore
estritamente binária) é uma árvore na qual todos os outros Nós do que as folhas tem
dois Filhos.
• Uma árvore binária perfeita é uma árvore binária completa em todas as folhas que
estão na mesma profundidade ou mesmo nível. [3] (Esta é ambígua também chamada de
árvore binária completa.)
• Uma árvore binária completa é uma árvore binária na qual todos os níveis, exceto
possivelmente o último, está completamente cheio, e todos os Nós são os mais à
esquerda possível. [4]
• Uma árvore binária completa infinito é uma árvore com níveis, onde para cada nível
d o número de Nós existentes a nível d é igual a 2 d. O número cardinal do conjunto de
todos Nós é . O número cardinal do conjunto de todos os caminhos é . O
binário completo árvore infinita essencialmente descreve a estrutura do conjunto de
Cantor ; o intervalo de unidade sobre o eixo real (de cardinalidade ) É a imagem
contínua do conjunto de Cantor, esta árvore é chamado às vezes o espaço de Cantor .
• Uma árvore binária balanceada é onde a profundidade de todas as folhas difere por no
máximo, 1. Balanced as árvores têm uma profundidade previsível (quantos Nós são
percorridos desde a raiz até uma folha, raiz contando como Nó 0 e posterior como 1, 2,
..., profundidade). Esta profundidade é igual à parte inteira do l o g 2 (n) onde n é o
número de Nós na árvore equilibrada. Exemplo 1: árvore balanceada com um Nó, o l g 2
(1) = 0 (profundidade = 0). Exemplo 2: árvore balanceada com 3 Nós, o g l 2 (3) = 1,59
(profundidade = 1). Exemplo 3: árvore balanceada, com 5 Nós, o l g 2 (5) = 2,32
(profundidade da árvore é de 2 Nós).
• Uma árvore enraizada binário completo pode ser identificada com um magma livre .
• Um degenerado árvore é uma árvore onde para cada Nó Pai, há apenas um associado
Nó Filho. Isto significa que em uma avaliação de desempenho, a árvore se comportar
como uma estrutura de dados lista ligada.
- Note que essa terminologia varia frequentemente na literatura, especialmente no que diz
respeito ao significado "completo" e "cheio".
Prova
prova: n0 = 1 n2
Com a raiz, assim escolhidos, cada vértice terá um Pai exclusivamente definido, e até dois Filhos,
no entanto, até agora não há informação suficiente para distinguir um Filho esquerdo ou direito.
Se deixar cair a exigência de conectividade, permitindo que vários componentes ligados no
gráfico, que chamamos de uma estrutura de uma floresta.
Outra maneira de definir árvores binárias é uma definição recursiva em grafos dirigidos. Uma
árvore binária é:
• Um único vértice.
• Um gráfico formado por tomar duas árvores binárias, adicionando um vértice, e
adicionando uma borda dirigiu a partir do novo vértice para a raiz da cada árvore binária.
Isso também não estabelecer a ordem dos Filhos, mas não fixa um Nó raiz específica.
Combinatória
Os agrupamentos de pares de Nós em uma árvore pode ser representada como pares de letras,
cercada por parênteses. Assim, (ab) denota a árvore binária cuja subárvore esquerda é um
direito e cuja subárvore é b. Seqüências de pares de parênteses equilibrada pode ser utilizada
para designar árvores binárias em geral. O conjunto de todas as seqüências possíveis consiste
inteiramente de parênteses equilibrada é conhecida como a linguagem Dyck .
Dado n Nós, o número total de maneiras em que estes Nós podem ser organizados em uma
árvore binária é dada pelo número de Catalão n C. Por exemplo, C 2 = 2 declara que (a 0) e 0 (a)
são as únicas árvores binárias possível que Nós dois, e C 3 = 5 declara que ((a 0) 0), ((0 a 0) ), (0
(um 0)), (0 (0 a)) e (ab) são os únicos cinco árvores binárias possível que três Nós. Aqui 0
representa uma subárvore que não está presente.
Dada uma seqüência que representa uma árvore binária, o operador para obter a subárvore
esquerda e direita são muitas vezes referidos como carro e cdr .
Nós e as referências
Em uma linguagem com os registros e referências , árvores binárias são geralmente construídos
por ter uma estrutura de Nó de árvore que contém alguns dados e referências a seu Filho e
deixou seu Filho direito. Às vezes, ele também contém uma referência a seu Pai único. Se um
Nó que tem menos de dois Filhos, alguns dos ponteiros Filho pode ser definido como um valor
nulo especial, ou para um especial do linfonodo sentinela .
Em línguas com sindicatos marcou como ML , um Nó de árvore é muitas vezes uma união
etiquetada de dois tipos de Nós, um dos quais é a-tupla de dados, deixou três Filhos, eo Filho a
direita, e os outros de que é uma folha " "Nó, que não contém dados e funções bem como o
valor nulo em uma linguagem com ponteiros.
Lista Ahnentafel
Árvores binárias podem também ser armazenados como uma estrutura de dados implícitos em
arrays , e se a árvore é uma árvore binária completa, este método não desperdiça espaço. Neste
arranjo compacto, se um Nó possui um índice i, seus Filhos são encontrados em dois índices i + 1
(para a esquerda da criança) e 2 i + 2 (para a direita), enquanto a sua mãe (se houver) é
encontrada em índice (Supondo que a raiz tem índice zero). Isto beneficia método de
armazenamento compacto mais e melhor localização de referência , especialmente durante um
percurso pré-venda. No entanto, é caro para crescer e desperdiça espaço proporcional a 2 h - n
para uma árvore de altura h com n Nós.
A árvore binária pode também ser representada na forma de matriz, bem como adjacência lista
ligada. No caso da matriz, cada Nó (raiz, esquerda, direita) é simplesmente colocado no índice, e
não há nenhuma conexão mencionado sobre a relação entre Pais e Filhos. Mas, em
representação lista ligada, Pode-se encontrar a relação entre Pais e Filhos. Em representação de
matriz os Nós são acessados por meio do cálculo do índice. Este método é usado em linguagens
como FORTRAN, que não tem alocação dinâmica de memória. Nós não Pode-se inserir um novo
Nó na árvore binária matriz implementada com facilidade, mas isso é facilmente feito quando se
utiliza uma árvore binária implementada como lista ligada.
Métodos de iteração sobre árvores binárias
Muitas vezes, uma vontade de visitar cada um de Nós em uma árvore e analisar o valor lá.
Existem várias ordens comum, na qual os Nós podem ser visitados, e cada um tem propriedades
úteis que são explorados em algoritmos baseados em árvores binárias.
Pre-Order: Root em primeiro lugar, as crianças após o pós-ordem: crianças em primeiro lugar,
depois de raiz em ordem: à esquerda da criança, de raiz, o Filho da direita.
Codificação
A estrutura de dados sucinta é aquele que toma o mínimo possível de espaço absoluto, tal
como estabelecido por informações teóricas limites inferiores. O número de diferentes
árvores binárias em Nós n é C n, n º número da Catalunha (assumindo que vemos árvores com
estrutura idêntica idênticas). Para n grande, isto é cerca de 4 n, portanto precisamos de pelo
menos cerca de log 2 4 n = 2 n bits para codificá-lo. Uma árvore binária sucinta, pois, que
ocupam apenas 2 bits por Nó.
Uma representação simples que atende a esse limite é de visitar os nodos da árvore em pré-
venda, saída 1 "para um Nó interno e" 0 "para uma folha. [1] Se a árvore contém dados, Pode-se
simplesmente armazená-lo em simultâneo uma matriz consecutivos preorder. Esta função
realiza o seguinte:
A estrutura da cadeia só tem 2 n + 1 bits, no final, onde n é o número de (interno) Nós, Nós nem
sequer temos a loja de seu comprimento. Para mostrar que nenhuma informação é perdida,
Pode-se converter a saída de volta para a árvore original como este:
Existe um-para-um mapeamento entre um general ordenou árvores e árvores binárias, que em
particular é usado por Lisp para representar as árvores geral ordenou como árvores binárias.
Para converter uma árvore geral ordenou a árvore binária, só precisamos para representar a
árvore de maneira geral, criança-irmão esquerda. O resultado desta representação será
automaticamente árvore binária, se visto de uma perspectiva diferente. Cada Nó N da árvore
ordenada corresponde a um Nó N 'na árvore binária, deixou o Filho de N' é o Nó que
corresponde ao primeiro Filho do N, eo direito da criança N 'é o Nó correspondente ao' s N
próximo irmão --- isto é, o próximo Nó na ordem entre os Filhos do Pai de N. Esta representação
de árvore binária de uma árvore de ordem geral, é por vezes também referida como uma criança
Esquerda-direita da árvore binária irmão (árvore LCRS), ou uma árvore duplamente encadeadas ,
ou uma cadeia de Filial-Herdeiro .
Uma maneira de pensar sobre isso é que cada Nó crianças estão em uma lista ligada ,
encadeadas com os seus campos a direita eo Nó só tem um ponteiro para o início ou cabeça
dessa lista, através do seu campo de esquerda.
Por exemplo, na árvore à esquerda, um tem os 6 Filhos (B, C, D, E, F, G). Ela pode ser convertida
em árvore binária, à direita.
A árvore binária pode ser pensada como a árvore original inclinado lateralmente, com as bordas
pretas à esquerda representa o primeiro Filho e as bordas direita azul representando próximo
irmão. As folhas da árvore à esquerda seria escrita em Lisp como:
que seria aplicado na memória como a árvore binária à direita, sem qualquer correspondência
sobre os Nós que tem um Filho esquerdo.
Estruturas de Dados Árvores - Tree
S. Sudarshan
• Árvore
o Nodes
o Cada nó pode ter 0 ou mais filhos
o Um nó pode ter no máximo um pai
• Árvore binária
o Árvore com 0-2 filhos por nó
Árvore
Binary Tree
Árvores
• Terminologia
o ⇒ Root nenhum pai
o Folha ⇒ nenhuma criança
o ⇒ Interior não-folha
o Altura ⇒ distância da raiz até a última folha
nó raiz
nós folha
nós Interior
Altura
• propriedade Key
o Valor em nó
Os menores valores em subárvore esquerda
Valores maiores de subárvore direita
o Exemplo
X> Y
X <Z
• Exemplos
10
30
25
45
10
45
25
30
5
10
30
25
45
Nó da classe (
...
n retorno;
n = n-> esquerda;
return null;
return (n);
return (n);
• Pesquisar (raiz de 2)
10
30
2
25
45
10
30
25
45
10> 2, à esquerda
5> 2, à esquerda
2 = 2, encontrado
5> 2, à esquerda
2 = 2, encontrado
raiz
10
30
25
45
5
10
30
25
45
10 <25, a direita
25 = 25, encontrado
5 <25, direita
25 = 25, encontrado
• Equilibrado
o Height = O (log (n)) para nós n
o Útil para pesquisas
• Tempo de busca
o Proporcional à altura da árvore
o Balanced árvore binária
O (log (n)) tempo
o árvore degenerada
O (n) o tempo
Como pesquisar lista ligada / array unsorted
• Algoritmo
o Executar a busca para o valor X
o Pesquisa vai terminar no nó Y (se X não na árvore)
o Se X <Y, X inserir novas folhas como subárvore esquerda de novo para
Y
o Se X> Y, inserir novas folhas X como nova subárvore direita de Y
• Observações
o O (log (n)) para operação de árvore balanceada
o Inserções árvore desequilíbrio pode
Exemplo de Inserção
• Insert (20)
10
30
25
45
10 <20, direita
20
• Algoritmo
o Executar a busca para o valor X
o Se X é uma folha, exclua X
o Else / / deve excluir nó interno
a) Substituir o maior valor de Y na subárvore esquerda
• Observação
o O (log (n)) para operação de árvore balanceada
o Supressões árvore desequilíbrio pode
• Delete (25)
10
30
25
45
10 <25, a direita
25 = 25, excluir
10
30
45
Exemplo de exclusão (nó interno)
• Apagar (10)
10
30
25
45
30
25
45
30
25
45
• Delete (10)
10
30
25
45
25
30
25
45
25
30
45
Excluindo folha
árvore resultante
Balanced Trees Search
• Árvores sintáticas
o Converter a partir de representação textual para a representação da
árvore
o programa Textual em árvore
Usados extensivamente em compiladores
o Árvore de representação de dados
HTML por exemplo, dados podem ser representados como
uma árvore
chamada DOM (Document Object Model) da árvore
XML
Assim como o HTML, mas usada para representar dados
Tree estruturado
Parse Trees
-%
A*4*
/2D5
C5
Tree Traversal
if (esquerda! = NULL) (
Saída: A - C / 5 * 2 + D *% 5 4
+
-%
A*4*
/2D5
C5
• pré-ordem e pós-ordem:
Saída: + - * A / C 5 2% * D 5 4
Saída: A C 02/05 * - * D 5 + 4%
-%
A*4*
/2D5
C5
XML
• Representação de Dados
o Por exemplo,
<dependency>
<object> sample1.o </ object>
<Sample1.cpp <depends> / depende>
<depends> <sample1.h / depende>
<Rule> g + + sample1.cpp <c-regra> /
</> Dependência
o representação da árvore
dependência
objeto
depende
sample1.o
sample1.cpp
depende
sample1.h
regra
g + +-c ...
Estruturas de Dados Gráfico
Ahm'bad
Délhi
Mumbai
Calcutá
Chennai
Madurai
Fim do Capítulo
Lista Estática Seqüencial
Uma lista estática sequencial é um arranjo de registros onde estão estabelecidos
regras de precedência entre seus elementos ou é uma coleção ordenada de
componentes do mesmo tipo.
O sucessor de um elemento ocupa posição física subsequente.
Ex: lista telefônica, lista de alunos
Mas, absolutamente, uma lista estática sequencial ou é vazia ou pode ser escrita
como ( a(1), a(2), a(3), ... a(n) ) onde a(i) são átomos de um mesmo conjunto S.
Além disso, a(1) é o primeiro elemento, a(i) precede a(i+1), e a(n) é o último
elemento.
Vantagem:
Quando usar:
• listas pequenas
• inserção/remoção no fim da lista
• tamanho máximo bem definido
Referências