Unive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA
-UFES Prof. Marcelo Otone Aguiar
marcelo.aguiar@ufes.br
www.marceloaguiar.pro.br
Universidade Federal do Espírito Santo Centro de Ciências Agrárias – CCA-UFES
Departamento de Computação
Busca e Ordenação em Memória
Secundária
Estrutura de Dados II
Estrutura de Dados II COM10078 - 2016-II Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFES Universidade Federal do Espírito Santo - Busca e Ordenação em memória Secundária
‣Quicksort Externo;
‣Acesso Indexado;
‣Árvores n-árias;
‣Indexação por espalhamento;
Conteúdo Programático da Disciplina
2
C.H. Prevista 12 horas
rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Ordenação Externa
3 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCAOrdenação Externa
•
A ordenação externa consiste em ordenar arquivos detamanho maior que a memória interna disponível.
•
Os métodos de ordenação externa são diferentes dos deordenação interna.
•
Os algoritmos devem diminuir o número de acesso àsunidades de memória externa.
•
Nas memórias externas, os dados ficam em um arquivosequencial.
•
Apenas um registro pode ser acessado em um dadoUnive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Ordenação Externa
•
Fatores que determinam as diferenças das técnicas deordenação externa em relação à ordenação interna:
•
Maior custo de acesso à memória para transferênciasdos dados entre a interna e externa
•
Restrições de acesso a dados, como o acesso apenassequencial ou o custo do acesso
•
Os métodos são dependentes do estado atual datecnologia 5 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFE
S Universidade Federal do Espírito Santo
Ordenação Externa
•
O método mais importante de ordenação externa é o deordenação por intercalação
•
Intercalar é combinar dois ou mais blocos ordenadosem um único bloco ordenado
•
A intercalação é utilizada como operação auxiliar naordenação
•
O foco dos algoritmos de ordenação externa é reduzir onúmero de acessos ao arquivo.
•
Uma boa medida de complexidade de um algoritmo deordenação por intercalação é o número de vezes que um item é lido ou escrito na memória interna.
•
Os bons métodos de ordenação externa geralmenteenvolvem menos do que dez passadas sobre o arquivo. 6
rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Ordenação Externa
•
Estratégia geral dos métodos de ordenação externa:1.
Quebre o arquivo em blocos do tamanho da memóriainterna disponível.
2.
Ordene cada bloco na memória interna.3.
Intercale os blocos ordenados, fazendo váriaspassadas sobre o arquivo.
•
A cada acesso são criados blocos ordenados cadavez maiores, até que todo o arquivo esteja ordenado.
7 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA
Mergesort Externo
Unive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Mergesort Externo
•
Método mais comum da ordenação externa.
•
Utiliza a técnica de intercalação: combina dois ou
mais blocos ordenados em um único bloco, maior,
ordenado.
•
Funcionamento:
•
RAM comporta
“n” registros de dados
•
Carregar parte do arquivo na RAM
•
Ordenar os dados na RAM com um algoritmo
•
In-place: ex. Quicksort
•
Salvar os dados ordenados em um arquivo
separado
9 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFES Universidade Federal do Espírito Santo
Mergesort Externo
•
Funcionamento (continuação):•
Repetir os anteriores até terminar o arquivo original•
Ao final, temos “k” arquivos ordenados•
“Multi-way merging”•
Criar “k+1” buffers de tamanho “n/(k+1)” (“1” desaída, “k” de entrada)
•
Carregar parte dos arquivos ordenados nos “buffersde entrada”, intercalar no “buffer de saída”
•
Buffers de entrada “vazio”: carregar mais dados•
Buffers de saída “cheio”: salvar dados10
Tamanho máximo de dados na memória
rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Mergesort Externo
11
Arquivo não ordenado
Multi-way merging Arquivo ordenado k ordenações na RAM k arquivos ordenados Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA
Unive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES 13 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFE
S Universidade Federal do Espírito Santo 14
Buffer cheio:
Salva em disco
Sobraram dados n
o Buffer: Salva em
disco
Nº arquivos geradosrsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES 15
Controla a mudança
de linha no final do a
rquivo
Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCAstruct para gerenciar os
buffers
Quantidade de elementos que pode carregar na memória para cada um dos buffers
Unive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
17
Existe menor elemento? Coloca no buffer de saída. Salvar se buffer cheio.
Sobraram dados no buffer? Salvar em arquivo.
Se verdadeiro, então buffer de saída está cheio. Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFE
S Universidade Federal do Espírito Santo 18
Procura menor valor na primeira po sição de cada buffer
Achou menor. Atualiza posição do buf fer. Encher se estiver vazio.
rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
19
Tem dados no arquivo? Lê e coloca no buffer Acabou os dados. Fecha arquivo. Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA
Árvores n-árias
Unive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Árvores n-árias
21
•
As árvores binárias de pesquisa são estruturas muito eficientes quando se deseja trabalhar com tabelas que caibam inteiramente na memória principal do computador.•
Satisfazem condições e requisitos diversificados e conflitantes, tais como acesso direto e sequencial, facilidade de inserção e retirada de registros e boa utilização de memória.•
Uma forma simplista de resolver o problema de recuperar informação em grandes arquivos de dados é:•
Armazenar os nós da árvore no disco,•
e os apontadores à esquerda e à direita de cada nó se tornam os endereços de disco em vez de endereços memória principal. Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFES Universidade Federal do Espírito Santo
Árvores n-árias
22
•
Para diminuir o número de acessos a disco, os nós da árvore podem ser agrupados em páginas.•
A forma de organizar os nós da árvore dentro de páginas é muito importante sob o ponto de vista do número esperado de páginas lidas quando se realiza uma pesquisa na árvore.•
Um método de alocação de nós em páginas que leva em consideração a relação de proximidade dos nós dentro da estrutura da árvore foi proposto por Muntz e Uzgalis (1970).•
Neste método o novo nó a ser inserido é sempre colocado na mesma página do nó pai. Se o nó pai estiver em uma páginacheia, então uma nova página é criada e o novo nó é colocado
rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Árvores n-árias
23
•
Knuth (1973) mostrou que o número esperado de acessosa páginas em uma pesquisa na árvore é muito próximo do ótimo.
•
Contudo, a ocupação média das paginas é extremamentebaixa, da ordem de 10%, o que torna o algoritmo inviável para aplicações práticas.
•
Uma solução brilhante para esse problema,simultaneamente a uma proposta para manter equilibrado o crescimento da árvore é permitir inserções e retiradas a vontade. Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA
Árvores B
•
Quando uma árvore de pesquisa possui mais de um registro por nó ela deixa de ser binária.•
Essas árvores são chamadas de n-árias, pelo fato de possuírem mais de dois descendentes por nó.•
Neste caso, os nós são comumente chamados de páginas.•
A árvore B é n-ária. Em uma árvore B de ordem m, temos que:•
Cada página contém no mínimo m registros (e m + 1 descendentes) e no máximo 2m registros (e 2m + 1descendentes), exceto a página raiz, que pode conter entre 1 e 2m registros.
Unive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Árvores B
•
Uma árvore B de ordem m = 2 com três níveis pode ser vista abaixo.•
Todas as páginas contêm (entre m e 2m chaves) dois, três ou quatro registros, exceto a raiz, que pode conter entre 1 e 2m chaves.•
Os registros aparecem em ordem crescente da esquerda para a direita. 25 30 10 20 40 50 3 4 8 9 11 13 17 25 28 33 36 43 45 48 52 55 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFES Universidade Federal do Espírito Santo
Operações Básicas com Árvore B
•
Criação de uma árvore B vazia•
Busca na árvore B•
Inserção na árvore B•
Remoção na árvore Brsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Árvore B
#define ORDEM 2 typedef struct { int chave; char nome[20]; int idade; int ApPage[2]; int rank; } Registro;typedefstruct Pagina_str *Apontador;
typedefstruct Pagina_str {
int n; int pageNum; int num; Registro r[2 * ORDEM]; Apontador p[2 * ORDEM+1]; } Pagina; struct Node{ Registro info;
struct Node *prox; };
typedefstruct Node node;
27 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA
Inicializar uma Árvore B
typedef Apontador TipoDicionario;
void inicializa(TipoDicionario *Dicionario) {
*Dicionario = NULL;
}
void inicia(node *LISTA)
{
Unive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Busca em Árvore B
•
A busca na árvore B é semelhante à busca na árvorebinária
•
É executado o mesmo caminho•
Contudo, é necessário acrescentar verificações relativasàs chaves existentes em cada página, que determinam qual o próximo passo do percurso
29 * 4 * 8 * *12 * 3 * * 18 * * * 25*27 * * 32 * * * 40 * * * 60*61 * * 72 * * *9 * 17 * * 30*36 * * 70 * * * 22*58 * Busca da chave 18 em uma árvore B de ordem 1 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFE
S Universidade Federal do Espírito Santo
Busca em Árvore B
•
O algoritmo de busca compara a chave com as chaves donó raiz.
•
Se não encontrar, então a busca prossegue em um certofilho dessa página, observando a seguinte propriedade:
•
Todas as chaves armazenadas no filho apontado por Pj em uma página são menores que a chave kjarmazenada nessa página. Todas as chaves
armazenadas no filho apontado por Pj+1 são maiores que a chave kj.
rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Busca em Árvore B
void Busca(Registro Reg, Apontador Ap) {
int i =1;
if (Ap == NULL) {
printf(“Chave nao encontrada!\n”);
return; }
while (i < Ap->n && Reg.Chave > Ap->r[i-1].Chave)
i++;
if(Reg.Chave == Ap->r[i-1].Chave) {
buscainFile(Ap->r[i-1], Ap);
return; }
if (Reg.Chave < Ap->r[i-1].Chave)
Busca(Reg, Ap->p[i-1]); else Busca(Reg, Ap->p[i]); } 31 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA
Busca em Árvore B
voidbuscainFile(RegistroReg, Apontador pagina) {
Registroreg[2*ORDEM]; inti;
FILE *arq = fopen(namefile,"rb"); if (arq == NULL)
exit(1);
fseek(arq, pagina->pageNum*(2*ORDEM*sizeof(Registro)), SEEK_SET); fread(reg, (2*ORDEM*sizeof(Registro)),1,arq);
fclose(arq);
for(i = 0; i < 2*ORDEM; i++){ if (Reg.chave == reg[i].chave)
printf("%s%d\n",reg[i].nome,reg[i].idade); }
Unive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Inserir Registro
•
O primeiro passo é localizar a página apropriada em que o novo registro deve ser inserido, se o registro já existir o registro não deve ser incluído novamente.•
Se o registro a ser inserido encontra seu lugar em uma página com menos de 2m registros, o processo de inserção fica limitado àquela página (deve se garantir a ordenação).•
Se a página estiver cheia então ela deve ser dividida em duas e a chave do meio deve ser promovida, ou seja, ela vai ficar na página pai da folha em questão.•
Se nesta página não houver espaço para armazenamento da chave promovida, a divisão é repetida até que o problema seja resolvido. 33 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFES Universidade Federal do Espírito Santo
Inserir Registro
•
Registro 14 não encontrado e página 3 cheia•
Página 3 dividida em duas páginas, gerando página 4•
Os 2m + 1 são cinco registros, distribuídos igualmente entre páginas 3 e 4, o registro central, o 20 é movido para a página pai no nível. 34 10 3 4 8 9 16 20 25 29 2 1 3 10 20 3 4 8 9 25 29 2 1 3 14 16 4rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Exemplo
Ordem m=2
2 ≤ NE ≤ 4
Inserir 11 Inserir 53 Inserir 36 Inserir 95 Inserir 8 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCAExemplo 2
Ordem m=2 2 ≤ NE ≤ 4 25 52 75 90 Inserir 20 Inserir 35 8 11 16 21 27 31 36 48 53 59 63 72 78 81 91 95Unive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Função “Insere”
voidInsere(Registro Reg, Apontador *Ap) { intCresceu;
Registro RegRetorno; Apontador ApRetorno; Apontador ApTemp;
Ins(Reg, *Ap, &Cresceu, &RegRetorno, &ApRetorno); if (Cresceu) { /* Se arvore cresce na altura pela raiz */ ApTemp = (Apontador) malloc(sizeof(Pagina)); ApTemp->n = 1;
ApTemp->r[0] = RegRetorno; ApTemp->p[1] = ApRetorno; cont++;
ApTemp->pageNum = cont; ApTemp->p[0] = *Ap; *Ap = ApTemp; //save in file } saveAux(*Ap, 2*ORDEM); } 37 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFE
S Universidade Federal do Espírito Santo
Função “Ins”
void Ins(Registro Reg, Apontador Ap, int *Cresceu, Registro *RegRetorno,
Apontador *ApRetorno) { Apontador ApTemp; Registro Aux; int i, j; if (Ap == NULL) { *Cresceu = 1; *RegRetorno = Reg; *ApRetorno = NULL; return; } i = 1;
while (i < Ap->n && Reg.chave > Ap->r[i - 1].chave) i++;
if (Reg.chave == Ap->r[i - 1].chave) {
printf("chave ja existente: %d \n", Reg.chave); *Cresceu = 0;
return; }
rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Função “Ins”
if (Reg.chave < Ap->r[i - 1].chave)
Ins(Reg, Ap->p[i-1], Cresceu, RegRetorno, ApRetorno); else
Ins(Reg, Ap->p[i], Cresceu, RegRetorno, ApRetorno); if (!*Cresceu)
return;
if (Ap->n < 2*ORDEM) { /* Verificando se a pagina tem espaco */ InsereNaPagina(Ap, *RegRetorno, *ApRetorno);
*Cresceu = 0; return; }
/* Split: Pagina tem que ser dividida */
ApTemp = (Apontador) malloc(sizeof(Pagina));
ApTemp->n = 0;
ApTemp->p[0] = NULL;
cont++;
ApTemp->pageNum = cont;
39 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA
Função “Ins”
if (i <= ORDEM + 1) {InsereNaPagina(ApTemp, Ap->r[2 * ORDEM - 1], Ap->p[2 * ORDEM]); Ap->n--;
InsereNaPagina(Ap, *RegRetorno, *ApRetorno); }
else {
InsereNaPagina(ApTemp, *RegRetorno, *ApRetorno); }
for (j = ORDEM + 2; j <= 2 * ORDEM; j++)
InsereNaPagina(ApTemp, Ap->r[j - 1], Ap->p[j]); Ap->n = ORDEM; ApTemp->p[0] = Ap->p[ORDEM + 1]; *RegRetorno = Ap->r[ORDEM]; *ApRetorno = ApTemp; for (j = ORDEM; j < Ap->n + 2; j++){ Aux.chave = 0;
Unive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Função “InsereNaPagina”
void InsereNaPagina(Apontador Ap, Registro Reg, Apontador ApDir) {
intk;
intNaoAchouPosicao; k = Ap->n;
NaoAchouPosicao = k > 0;
while (NaoAchouPosicao) {
if (Reg.chave >= Ap->r[k - 1].chave) { NaoAchouPosicao = 0; break; } Ap->r[k] = Ap->r[k - 1]; Ap->p[k + 1] = Ap->p[k]; k--; if (k < 1) NaoAchouPosicao = 0; } Ap->r[k] = Reg; Ap->p[k + 1] = ApDir; Ap->n++; } 41 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFE
S Universidade Federal do Espírito Santo
Remover Registro
•
Quando a página que contém o registro a ser retirado é uma página folha, a operação é simples.•
No caso de não ser uma página folha, o registro a ser retirado deve ser o primeiro substituído por um registro contendo uma chave adjacente (antecessora ou sucessora).•
Para localizar uma chave antecessora, basta procurar pela página folha mais à direita na subárvore à esquerda, exemplo:42
30
10 20 40 50
rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Remover Registro
•
Tão logo o registro seja retirado da página folha, énecessário verificar se pelo menos m registros passam a ocupar a página.
•
Quando menos de m registros passam a ocupar a página,isso significa que a propriedade árvore B é violada.
•
Para reconstituir a propriedade da árvore B, é necessáriotomar emprestado um registro da página vizinha.
43 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA
Remover Registro
•
Existem duas possibilidades:•
Primeira, o número de registros na página vizinha émaior que m: basta tomar um registro emprestado e trazê-lo para a página em questão via página pai.
•
Segunda possibilidade, não existe um númerosuficiente na página vizinha: nesse caso, o número total de registros nas duas páginas é 2m-1 e,
consequentemente as duas páginas tem que ser fundidas em uma só, tomando emprestado da página pai o registro do meio.
Unive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Exemplo
Ordem m=2 2 ≤ NE ≤ 4
52
Remover 52 (buscar o maior da esquerda ou menor da direita) Remover 75 (mesma estratégia)
Remover 91 (fazer a junção com outra página [pai e irmão])
Remover 16 (fazer a junção com pai e irmão da direita ou esquerda)
15 25 35 75 90 53 59 63 72 16 21 8 11 27 31 36 48 78 81 91 95 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFE
S Universidade Federal do Espírito Santo
Função “Retira”
void Retira(intCh, Apontador *Ap)
{
int Diminuiu; Apontador Aux;
Ret(Ch, Ap, &Diminuiu);
if (Diminuiu && (*Ap)->n == 0) { /* Arvore diminui na altura */ Aux = *Ap; *Ap = Aux->p[0]; free(Aux); } } 46
rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Função “Retira”
void Ret(intCh, Apontador *Ap, int *Diminuiu) {
int Ind, j;
Apontador WITH; Registro Reg; if (*Ap == NULL) {
printf("chave nao encontrada: %i\n", Ch); *Diminuiu = 0;
return; }
WITH = *Ap; Ind = 1;
while (Ind < WITH->n && Ch > WITH->r[Ind - 1].chave) Ind++;
if (Ch == WITH->r[Ind - 1].chave) { Reg.chave = 0;
Reg.rank = 0;
WITH->r[Ind -1] = Reg;
47 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA
Função “Retira”
if (WITH->p[Ind - 1] == NULL) { /* Pagina folha */WITH->n--;
*Diminuiu = WITH->n < ORDEM; for (j = Ind; j <= WITH->n; j++) { WITH->r[j - 1] = WITH->r[j]; WITH->p[j] = WITH->p[j + 1]; }
return; }
Antecessor(*Ap, Ind, WITH->p[Ind - 1], Diminuiu); if (*Diminuiu)
Reconstitui(WITH->p[Ind - 1], *Ap, Ind - 1, Diminuiu); return;
}
if (Ch > WITH->r[Ind - 1].chave) Ind++;
Unive rsid ade Fe d e ra l d o Es p ír it o S anto - CCA -UFES
Universidade Federal do Espírito Santo CCA-UFES
Função “Antecessor”
void Antecessor(Apontador Ap, int Ind, Apontador ApPai, int *Diminuiu)
{
if (ApPai->p[ApPai->n] != NULL) {
Antecessor(Ap, Ind, ApPai->p[ApPai->n], Diminuiu); if (*Diminuiu)
Reconstitui(ApPai->p[ApPai->n], ApPai, ApPai->n, Diminuiu); return;
}
Ap->r[Ind - 1] = ApPai->r[ApPai->n - 1]; ApPai->n--;
*Diminuiu = ApPai->n < ORDEM; } 49 Un iv er sid ad e Fed er al d o Es p ír it o S an to - CCA -UFE
S Universidade Federal do Espírito Santo