Buscar

prova

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 7 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 7 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Modelo cosequencial - É um processamento coordenado de duas ou mais listas em disco 
para produzir uma única lista em disco. 
Pontos importantes: 
- Inicialização: como abrir os arquivos corretamente 
- Sincronização: como avançar adequadamente em cada arquivo 
- Gerenciamento de condições de fim de arquivo e fim de listas 
- Reconhecimento de erros: nomes duplicados ou fora de ordem 
 
Merging (Intercalação) – União de 2 listas 
Um nome duplicado deve ser gravado na lista uma única vez. As listas devem ser lidas até o 
final. 
Base do processo de ordenação de arquivos muito grandes, cujo índice não cabe na memória 
principal. 
 
Algoritmo: 
- Abre os arquivos lista 1 e lista 2 
- Cria um arquivo de saída 
- Seta a variável existe_nome para verdadeiro 
- Chama o nome 1 da lista 1 
- Chama o nome 2 da lista 2 
- Enquanto existirem nomes, se o nome 1 for menor que o nome 2, então escreve o nome 1 na 
saída e chama o proximo nome da lista 1, se o nome 1 for menor que o nome 2, então escreve 
o nome 2 e chama o proximo nome da lista 2, se os nomes forem iguais, então escreve o nome 
1 e chama o próximo nome da lista 1 e da lista 2. 
 
n1 = read_name(list1); 
n2 = read_name(list2); 
while (!eof(list1) || !eof(list2)) { 
if (n1 < n2) { 
write_name(n1,list3); 
n1 = read_name(list1); 
} 
if (n1 > n2){ 
write_name(n2,list3); 
n2 = read_name(list2); 
} 
else{ 
/* n1 == n2 */ 
write_name(n1,list3); 
n1 = read_name(list1); 
n2 = read_name(list2); 
} 
} 
 
Matching (Intersecção) – Produzir nomes comuns em ambas as listas assumindo que não 
contenham nomes repetidos e que esteja em ordem crescente. 
Termina ao final da menor lista. 
Útil nas operações que fazem combinação (AND) dos resultados após busca em vários índices. 
 
Algoritmo: 
- Abre os arquivos lista 1 e lista 2 
- Cria um arquivo de saída 
- Seta a variável existe_nome para verdadeiro 
- Chama o nome 1 da lista 1 
- Chama o nome 2 da lista 2 
- Enquanto existirem nomes, se o nome 1 for menor que o nome 2, então chama o próximo 
nome da lista 1, se o nome 1 for maior que o nome 2, então chama o próximo nome da lista 2, 
se os nomes forem iguais, então escreve o nome 1 na lista de saída e chama o próximo nome 
da lista 1 e da lista 2. 
 
n1 = read_name(list1); 
n2 = read_name(list2); 
while (!eof(list1) && !eof(list2)) { 
if (n1 < n2) 
n1 = read_name(list1); 
else if (n1 > n2) 
n2 = read_name(list2); 
else{ 
 /* n1 == n2 */ 
write_name(n1,list3); 
n1 = read_name(list1); 
n2 = read_name(list2); 
} 
} 
 
Intercalação em K-vias 
- Pode ordenar arquivos realmente grandes. 
- Processamento cosequencial com mais de 2 arquivos. 
- Geração, leitura e escrita das corridas é seqüencial (mais rápido e pode utilizar fitas). 
Ideia: Le registros para a memória até lotar, ordena os registros na memória (ordenação 
interna) e escreve os registros ordenados em um sub-arquivo chamado de corrida e vai 
repetindo para o resto do arquivo criando várias corridas. Assim é feita a intercalação nas 
corridas criando o arquivo completamente ordenado. 
No keysorting, as chaves tinham que caber em memória e após a ordenação era necessários 
vários seekings para criar o arquivo ordenado. 
 
 
HeapSort 
O HeapSort pode começar a fazer a ordenação a partir da leitura das chaves. 
Ou seja, ele começa a trabalhar a medida que os números são lidos, comparando as chaves a 
medida que elas são encontradas. 
- Cada nó possui uma única chave >= chave do nó pai. 
- Todas as folhas estão em no máximo 2 níveis e todas as folhas do nível mais baixo estão 
mais à esquerda. 
- Heap pode ser mantida em vetor. 
Filho esquerdo = 2i 
Filho direito = 2i+1 
Nó pai = Menor inteiro igual a j/2 
 
Dividida em suas fases: 
- Construção da heap (a partir da leitura das chaves) 
- Escrita das chaves ordenadamente 
 
Algoritmo de inserção: 
- Coloca o valor a ser inserido na última posição da heap. 
- Compara o valor inserido com o valor da chave do nó pai. 
- Troca os valores de posição se o valor inserido é menor que o nó pai. 
- Faz a troca até que o valor inserido seja maior ou igual ao valor do nó pai ou até atingir a raiz. 
 
Algoritmo de remoção: 
- Remove o valor que está na raiz da árvore (a menor chave). 
- Move o elemento da última posição para a raiz. 
- Ajusta a heap com tamanho menor em um elemento. 
- Enquanto K for maior que o menor dos seus filhos, troque K pelo menor filho. 
 
O buffer de entrada evita o número excessivo de seeks, mas não permite que a leitura seja 
feita paralelamente a construção da heap. O uso de múltiplos buffers fazem com que enquanto 
as chaves de um bloco são processadas, os blocos seguintes já podem ser lidos. 
O número de buffers é igual ao número de blocos do arquivo. 
Assim que um bloco de registros é ordenado, ele pode ser escrito para o arquivo de saída, 
enquanto o próximo bloco é processado e assim por diante. 
Toda operação de E/S é seqüencial então o número de operações de seek é o menor possível. 
 
Merge Sort 
Envolve 2 fases: 
- Geração de corridas: Os segmentos do arquivo (corridas) são ordenados em memória RAM, 
usando algum método como HeapSort e gravados em disco. As corridas vão sendo gravadas a 
medida em que são geradas. 
- Intercalação: As corridas geradas são intercaladas formando o arquivo ordenado. 
Essa solução pode ordenar arquivos muito grandes e a geração, leitura das corridas e escrita 
final envolvem apenas acesso seqüencial. 
 
Pontos considerados no custo do MergeSort: 
- Leitura dos registros para a memória para a criação de corridas. 
- Escrita das corridas ordenadas para o disco 
- Leitura das corridas para intercalação 
- Escrita do arquivo final em disco 
 
O tempo de leitura de cada corrida inclui o tempo de acesso a cada bloco (seek + rotation 
delay) + tempo que leva para transferir cada bloco. Escrita idem a leitura. 
 
Maneiras de reduzir o tempo: 
- Usar mais hardware 
- Realizar a intercalação em mais de um passo, reduzindo a ordem de cada intercalação e 
aumenta o tamanho do buffer para cada corrida. 
- Aumentar o tamanho das corridas iniciais ordenadas. 
- Achar meios de realizar I/O simultâneo. 
 
Ao invés de intercalar todas as corridas ao mesmo tempo, o grupo é dividido em grupos 
menores e a intercalação é feita para cada sub-grupo, alocando um espaço maior para cada 
corrida e portanto necessitando de um numero menor de seeks. 
Em geral, corridas iniciais maiores implicam em um numero menor de corridas, o que implica 
em uma intercalação de ordem menor, com buffer maiores, resultando em numero menor de 
seeks. 
 
Replacement Selection – Quantidade de registros do arquivo é maior do que a memória 
interna. 
Dobrar o tamanho das corridas reduz o numero de seeks pela metade. 
É uma solução para aumentar o tamanho das corridas sem usar mais memória. 
Selecionar na memória a menor chave, escreve-la no arquivo e saída e usar seu lugar para 
uma nova chave 
Algoritmo: 
- Ler conjunto de registros e ordenar usando HeapSort. 
- Ao invés de escrever a heap inteira e gerar uma corrida, escreve apenas o registro com 
menor chave. 
- Busca um novo registro no arquivo de entrada e compara com a chave que acabou de ser 
escrita. Se ela for maior, insere o registro normalmente na heap. Se ela for menor que qualquer 
chave já escrita, insere o registro na heap secundaria. 
- Repete o passo anterior enquanto existirem registros a serem lidos. Por fim, transforma a 
secondary heap em primary heap e assim sucessivamente. 
 
Custos de usar replacement selection: Precisa de buffers para I/O e portanto, não pode usar 
toda a memória disponível para ordenação. 
 
Melhorar ordenação externa: 
- Para ordenação interna usar heapsort para formar corridas e Double buffering para sobrepor 
o processamento com input e output. 
- Usar o máximo de memória possível permitindo corridas maiores e buffers maiores na fase deintercalação. 
- Quando o numero de corridas é muito grande, usar intercalação em múltiplos passos, 
aumenta o tempo de transmissão mas diminui o numero de seeks. 
- Utilize Replacement Selection para formação da corrida inicial, especialmente se as corridas 
estiverem parcialmente ordenadas. 
 
Árvores Binárias Paginadas 
Tempo: O(logm n), onde m é o tamanho do nó (página). 
Pior caso para árvore binária completa perfeitamente balanceada: log2 (N+1) 
Versão em páginas: logk+1 (N+1), onde N é o numero total de chaves e k é o numero de chaves 
armazenadas em uma pagina. 
O problema fundamental associado a manutenção de um índice em disco é que o acesso é 
muito lento causando problemas para uma manutenção eficiente. 
Pesquisa binária (melhor solução até agora) requer muitos acessos e pode ficar caro manter 
um índice ordenado para permitir a busca binária. Precisamos que a inserção e eliminação dos 
registros não exijam reorganização total do índice. 
Os ponteiros esq e dir indicam onde estão os registros filhos e a estrutura pode ser mantida em 
memória secundária já que os ponteiros para os filhos dão o RRN das entradas 
correspondentes aos filhos e a sua localização no arquivo. 
 
Vantagens: 
- A ordem lógica dos registros não está associada a ordem física do arquivo. 
- O arquivo física do índice não precisa mais ser mantido ordenado, pois o que interessa é 
poder recuperar a estrutura lógica da árvore através dos campos esq e dir. 
Quando acrescentamos uma nova chave ao arquivo precisa-se saber apenas onde inserir na 
árvore. 
 
Desvantagem da árvore binária: 
- A altura tende a ser muito grande em relação ao numero de nós ou registros que ela contem. 
 
A árvore precisa estar balanceada para que não seja necessários muitos acessos adicionais. 
Nas árvores AVL a diferença de altura entre as duas sub-arvores compartilhando a mesma raiz 
é no máximo 1. 
Árvore AVL não requer ordenação do índice e reorganização na inserção mas há numero 
excessivo de acessos a disco. 
 
Nas árvores binárias paginadas a busca por uma posição especifica no disco é muito lenta, 
mas uma vez encontrada a posição, é possível ler uma grande quantidade de registros 
sequencialmente a um custo relativamente pequeno ecomizando acessos a disco. 
Combinação de busca (seek) lento e transferência rápida!!! 
Uma vez realizado um seek, todos os registros em uma mesma página do arquivo são lidos, ao 
invés de recuperar apenas alguns bytes. 
 
Desvantagens: Maior tempo na transmissão de grande quantidades de dados e a necessidade 
da manutenção da organização da arvore. 
 
Construção Top-Down – Construídas de cima pra baixo, é feita a partir da raiz, sendo que, 
cada vez que uma chave é inserida, a arvore dentro da página é rotacionada, se necessário, 
para manter o balanceamento. 
Difícil garantir que as chaves na página raiz dividam o conjunto de chaves de maneira 
balanceada e que cada pagina contenha um numero mínimo de chaves. 
Construção Bottom-Up – Construídas de baixo pra cima, as chaves na raiz da árvore emergem 
naturalmente, sendo desnecessário setar a raiz e depois encontrar formas de alterá-la. 
 
Árvore-B – é do tipo bottom-up e quando o nó fica cheio, ele é dividido (splitting) e uma chave 
é promovida (promoting). 
As árvores B permitem manter mais de uma chave em cada nó da estrutura, proporciona 
organização de ponteiros de forma que as operações são executadas rapidamente e assegura 
que todas as folhas se encontram no mesmo nível não importando a ordem de entrada dos 
dados. 
São arvores balanceadas desenvolvidas minimizar o numero de acessos ao disco 
maximizando o numero de filhos de um nó. 
Como o custo do acesso a disco é muito alto, toda vez que ele é feito, deve ser aproveitado da 
melhor maneira possível, trazendo o máximo de informação. 
A quantidade de dados utilizados numa árvore B não cabem na memória, por isso é necessário 
paginá-la. 
Para inserir uma nova chave numa folha cheia, o nó folha é dividido (split) em dois nós folhas 
distribuindo as chaves igualmente entre os nós. Então promovemos uma das chaves que estão 
nos limites de separação das folhas. 
 
Inserção (casos): 
1. Uma chave é colocada em uma folha que ainda tem algum espaço 
2. A folha na qual uma chave precisa ser colocada está cheia 
3. A raiz da árvore B está cheia 
A ideia principal é dividir a folha cheia em duas e a chave do meio é promovida para a página 
pai. 
 
A árvore é balanceada com relação a altura e as chaves promovidas sempre são boas 
separadoras. 
Algoritmo é recursivo e trabalha em duas etapas: Operando intercaladamente nas páginas 
inteiras e dentro das páginas. 
A ordem de uma árvore-B é dada pelo número maximo de descendentes que um nó pode 
possuir. 
Ordem m = numero maximo de chaves em uma página é m-1. 
O numero mínimo de chaves de um nó é m/2 – 1. 
Altura máxima e acessos: D <= 1 + log[m/2] ((N+1)/2) 
 
Características de uma árvore B de ordem d 
- A raiz é uma folha ou tem no mínimo 2 filhos 
- Cada nó interno (não folha e não raiz) possui no mínimo d+1 filhos 
- Cada nó tem no máximo 2d + 1 filhos 
- Todas as folhas estão no mesmo nível 
 
N=4 
Máximo de valores por nó = 3 
Nó-folha:Mínimo de valores por nó = 2 
Nó não-folha:Mínimo de filhos = 2 
Máximo de filhos = 4 
 
Operações principais: 
- Pesquisa (Pesquisa externa ao nó: Desce pela arvore a procura da chave de interesse e 
Pesquisa interna ao nó: Faz busca seqüencial ou binária entre as chaves do nó. 
- Percurso 
- Inserção 
- Remoção 
 
Busca: A busca recebe o apontador para o nó raiz e a chave k sendo procurada. Se a chave k 
pertencer a arvore, o algoritmo retorna o nó ao qual ela pertence e o índice dentro do nó 
correspondente a chave procurada. 
 
procedimento buscaB(x, pt, encontrou, pos) 
p:= ptraiz; pt:= y; encontrou := 0; 
enquanto p ≠ y faça 
inicio 
 i:= 1; pos:= 1; pt:= p 
 enquanto i ≤ m faça % m é o número de chaves que a página p contém 
 inicio 
 se x > p.s[i] então i: = i+1; pos: = i + 1 
 senão inicio 
 se x = p.s[i] então 
 p:= y; encontrou := 1 % chave encontrada 
 senão p := p.pont[i-1] % mudança de página 
 i:= m + 2 
 fim 
 fim {enquanto} 
 se i = m + 1 então p:= p.pont[m] 
fim {enquanto} 
 
 
B-TREE-SEARCH(x, k) 
i ← 1 
while i ≤ n[x] and k > keyi[x] do 
i ← i + 1 
if i ≤ n[x] and k = keyi[x] then 
return (x, i) 
if leaf [x] then 
return NIL 
else DISK-READ(ci[x]) 
return B-TREE-SEARCH(ci[x], k) 
 
Particionamento 
- O particionamento da raiz é a unica forma de aumentar a altura da arvore. 
- Em alguns casos o particionamento se propaga para a raiz, então o nó raiz é particionado 
mas como ele não tem pai, cria-se um novo nó que passa a ser a nova raiz. 
 
Concatenação 
- Acontece se as páginas são irmãs adjacentes (tem o mesmo pai) e juntas possuem menos de 
2d chaves. 
 
Acesso Sequencial Indexado 
 
 
Hash 
A idéia básica é criar uma série de sub-listas no lugar de uma única lista maior. A partir da 
aplicaçao de uma determinada função chamada hashing sobre a chave de busca do elemento, 
decide-se em qual das sub-listas o elemento deve ser ou estar armazenado. Procede-se, 
entao, uma busca na sub-lista determinada. Portanto, ao invés de realizar a busca em toda a 
lista, faz-se uma busca num subconjunto da lista. 
Acesso a arquivo O(1), o número de seeks é sempre o mesmo não importa o quanto o arquivo 
possa crescer. 
Não requer ordenação, tornando a inserção tão rápida quanto o acesso. 
A função hashing transforma uma chave k em um endereço que é usado como base para o 
armazenamento e recuperação de registros. 
Hashing estático: o tamanho do espaço de endereçamento não muda. 
Deteriora após muitas inserções e remoções. 
Numero de buckets é fixo, se o arquivo encolhe muito o espaço é desperdiçado e o 
crescimento dos arquivos produz longas cadeias prejudicando a busca. 
Hashing dinâmico: o tamanho do espaço deendereçamento pode aumentar e diminuir. 
Número de buckets pode aumentar. 
 
Diferenças da indexação: 
- Os endereços são aleatórios. 
- Duas chaves podem levar ao mesmo endereço (colisão). 
 
Maneiras de reduzir colisões: 
- Espalhamentos dos registros usando uma função que os distribua por igual entre os 
endereços disponíveis. 
- Utilizar mais memória (espalhar poucos registros em muitos endereços). 
- Utilizar de mais de um registro por endereço. 
 
Objetivo: Função hashing espalhe as chaves da maneira mais uniforme possível entre os 
endereços disponíveis. 
 
Algoritmo: 
- Utilizar código ASCII de cada um dos caracteres para formar um numero. 
- Junta 2 e soma. 
- Dividir o resultado da soma pelo espaço de endereçamento para obter o endereço final. 
a = s MOD N. 
 
Alguns métodos: 
- Pegar o resto da divisão da chave pelo tamanho do espaço disponível. 
- Examinar as chaves em busca de um padrão. 
- Segmentar a chave em diversos pedaços e depois fundir os pedaços. 
- Dividir a chave por um numero. 
- Elevar a chave ao quadrado e pegar o meio. 
- Transformar a base. 
 
É preciso decidir quanto de espaço deve perder para reduzir o numero de colisões. 
 
Resolução de colisões: 
- Encadeamento aberto ou hashing fechado 
- Encadeamento interno ou overflow progressivo 
- Hashing aberto 
 
Overflow Progressivo – procura-se a próximo posição vazia do endereço-base da chave. 
Vantagem: simplicidade 
Desvantagem: agrupamento primário, com estrutura cheia a busca fica lenta, dificulta inserções 
e remoções. 
 
Buckets (cestos) – permitem armazenar mais de um registro em um mesmo endereço, escreve 
e le um cesto por vez. Melhora o desempenho do espalhamento pois aumenta a proporção de 
registros por endereço e diminui o numero de colisões. 
 
- O tamanho lógico do arquivo hash deve ser fixado antes do arquivo ser preenchido com 
registros. 
- Qualquer procedimento de inclusão, remoção ou alteração de um registro não deve quebrar a 
ligação entre o registro e o RRN. 
A inicialização do arquivo aloca espaço física para o arquivo antes de começar a armazenar os 
registros criando um arquivos de espaços vazios aumentando a probabilidade dos registros 
serem armazenados próximos uns dos outros no disco, facilitando o processamento 
seqüencial. 
 
Para trabalhar com hashing é necessário uma função de espalhamento e um mecanismo para 
tratar colisões. 
Melhor caso: O(1) 
Pior caso: O(n) 
 
Por que usar arvore-B ao invés de Hashing? 
- Não permite recuperar todos os elementos em ordem de chave. 
- Não permite recuperar o elemento com a maior ou menor chave, nem o antecessor e 
sucessor de uma determinada chave. 
 
A medida que o arquivo aumenta, torna-se mais freqüente a necessidade de procurar por 
registros fora do seu endereço-base deteriorando o desempenho e precisando de mais 
acessos do que se fosse mantido em arvore-B.

Outros materiais