Baixe o app para aproveitar ainda mais
Prévia do material em texto
UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Listas Lineares Antonio Alfredo Ferreira Loureiro loureiro@dcc.ufmg.br http://www.dcc.ufmg.br/~loureiro loureiro@dcc.ufmg.br http://www.dcc.ufmg.br/~loureiro UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Introdução • Uma lista linear é uma seqüência de zero ou mais itens x1, x2, . . . , xn • xi é de um determinado tipo • n representa o tamanho da lista linear • Propriedades das posições relativas dos itens em uma dimensão, supondo n ≥ 1: – x1 é o primeiro item da lista – xn é o último item da lista – xi precede xi+1 para i = 1,2, . . . , n− 1 – xi sucede xi−1 para i = 2,3, . . . , n • Listas são adequadas para aplicações onde não é possível prever a deman- da por memória, permitindo a manipulação de quantidades imprevisíveis de dados, de formato também imprevisível UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Conjunto de operações usuais Dado um Tipo Abstrato de Dados Lista é necessário definir um conjunto de operações, como o apresentado a seguir: 1. Criar uma lista linear vazia 2. Inserir um novo item imediatamente após o i-ésimo item 3. Retirar o i-ésimo item 4. Localizar o i-ésimo item para examinar e/ou alterar o conteúdo de seus componentes 5. Combinar duas ou mais listas lineares em uma lista única 6. Partir uma lista linear em duas ou mais listas 7. Fazer uma cópia da lista linear 8. Ordenar os itens da lista em ordem ascendente ou descendente, de acordo com alguns de seus componentes 9. Pesquisar a ocorrência de um item com um valor particular em algum com- ponente UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Comentários sobre as operações • Outras operações podem ser definidas em função da aplicação • A implementação dessas operações deve ficar “encapsulsada” de tal forma que as interfaces para sua utilização sejam as mesmas (na medida do possí- vel) independentemente das estruturas de dados utilizadas na implementação dessas operações UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Exemplo de operações comumente utilizadas 1. FLVazia(Lista) – Faz a lista ficar vazia 2. Insere(x, Lista) – Insere x após o último item da lista 3. Retira(p, Lista, x) – Retorna o item x que está na posição p da lista, retirando-o da lista e deslocando os itens a partir da posição p+1 para as posições anteriores 4. Vazia(Lista) – Esta função retorna true se a lista está vazia; senão retorna false 5. Imprime(Lista) – Imprime os itens da lista na ordem ocorrência UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de Listas • As duas representações mais utilizadas são: 1. Implementações através de arranjos 2. Implementações através de apontadores UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de Listas Através de Arranjos (Pascal) x1 ... xn ... 1 = Primeiro 2x2 Último−1 MaxTam const InícioArranjo = 1; MaxTam = 1000; type Apontador = integer; TipoItem = record Chave : TipoChave; {outros componentes} end; TipoLista = record {Vetor que contém os itens da lista} Item : array [1..MaxTam] of TipoItem; {Aponta para o primeiro item da lista} Primeiro : Apontador; {Aponta para a posição seguinte ao último item da lista} Último : Apontador; end; UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação: FLVazia, Vazia, Insere procedure FLVazia(var: Lista: TipoLista); begin {Uma lista vazia tem o apontador Primeiro apontando para InícioArranjo e o apontador Último para essa mesma posição} Lista.Primeiro := InícioArranjo; Lista.Último := Lista.Primeiro; end; {FLVazia} function Vazia (var Lista : TipoLista): boolean; begin {Uma lista está vazia quando os apontadores Primeiro e Último apontam para a mesma posição} Vazia := Lista.Primeiro = Lista.Último; end; {Vazia} procedure Insere (x: TipoItem; var Lista: TipoLista); begin if Lista.Último > MaxTam {Na lista cheia, Último aponta para a posição seguinte a MaxTam} then writeln(’Erro: Lista está cheia’) else begin Lista.Item[Lista.Último] := x; {Insere o item na posição Último} Lista.Último := Lista.Último + 1; {Incrementa o apontador Último} end; end; {Insere} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação: Retira, Imprime procedure Retira(p : Apontador; var Lista: TipoLista; var Item: TipoItem); var Aux:integer; begin {Um elemento não pode ser retirado se a lista está vazia ou é uma posição inexistente} if Vazia(Lista) or (p >= Lista.Último) then writeln(’Erro: Posição não existe’) else begin Item := Lista.Item[p]; {Retira o item da lista} Lista.Último := Lista.Último - 1; {Decrementa o contador} for Aux := p to Lista.Último - 1 do {Realoca os itens da lista para Lista.Item[Aux] := Lista.Item[Aux + 1]; não deixar "buracos"} end; end; {Retira} procedure Imprime(var Lista: TipoLista); var Aux: integer; begin {Imprime os itens existentes na lista} for Aux := Lista.Primeiro to Lista.Último - 1 do writeln(Lista.Item[Aux].Chave); end; {Imprime} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Vantagens e desvantagens da implementação de listas através de arranjos • Vantagem: – Economia de memória: os apontadores são implícitos nesta estrutura • Desvantagens: – O custo para inserir ou retirar itens da lista: no pior caso, pode causar o deslocamento de todos os itens – Em aplicações em que não existe previsão sobre o crescimento da lista, a utilização de arranjos em linguagens como Pascal e C pode ser problemá- tica porque neste caso o tamanho máximo da lista tem que ser definido em tempo de compilação. UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de listas através de apontadores HH ��x1 HH �� HH �� HH ������ Lista linear Célula cabeça ... nilxn • Em uma implementação de listas através de apontadores, cada item da lista é encadeado com o seguinte através de uma variável do tipo Apontador • Este tipo de implementação permite utilizar posições não contíguas de me- mória, sendo possível inserir e retirar elementos sem haver necessidade de deslocar os itens seguintes da lista • Uma lista é constituída de células • Cada célula contém um item da lista e um apontador para a célula seguinte • Célula cabeça aponta para a célula que contém x1 UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de listas através de apontadores • Objetivo: – Armazenar o endereço de memória de uma estrutura de dados. – Os identificadores para um tipo apontador (ponteiro) devem ser declarados – Exemplo: Na linguagem Pascal em uma seção type • Exemplo em Pascal: type Apontador = ^Célula; Célula = "definição do tipo Célula"; UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de listas através de apontadores (Pascal) • Uso do símbolo ^ : – Seja uma variável Ap do tipo Apontador – Essa variável pode conter o endereço na memória de uma variável do tipo Célula – Em uma lista encadeada, o tipo base usual para uma variável de apontador é uma estrutura record • record pode conter qualquer combinação de campos de dados e campos de apontadores, ambos executando papéis distintos no programa • Campos de dados: – Projetados para representar itens particulares de informações de um deter- minado record • Campos de ponteiros: – Projetados para apontar para outros records da lista ligada UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Mais conceitos • Heap: – Área especial de memória – Em geral, o compilador aloca todo o espaço de memória que não é utilizado pelo programa para o heap • Um apontador contém o endereço de memória da variável armazenada no heap e assim fornece um significado simbólico de referência a um endereço heap • Esses conceitos serão estudados em Sistemas Operacionais e Compiladores UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Comandos associados com apontadores em Pascal • new: – Comando para alocar na memória uma nova variável • Seja o seguinte trecho de programa: ... type Apontador = ^Célula; Célula = record Chave : integer; Prox : Apontador; end; var Ap : Apontador; ... begin new(Ap); ... UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Comandos associados com apontadores em Pascal • new(Ap) : – Ap pode conter um endereço de uma variável dotipo Célula – Aloca (cria) na memória uma nova variável dinâmica que corresponde ao tipo base de Ap, que neste caso é o tipo Célula – Como resultado da execução do comando é armazenado o endereço da variável dinâmica em Ap UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Comandos associados com apontadores em Pascal • dispose : – Comando para liberar a memória que foi previamente alocada a uma deter- minada variável dinâmica • dispose(Ap) : – Depois da execução de dispose , a variável Ap não tem um valor definido e não deve ser usado em nenhuma referência UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de listas através de apontadores (Pascal) type Apontador = ^Célula; TipoItem = record Chave : TipoChave; {outros componentes} end; Célula = record Item : TipoItem; Prox : Apontador; end; TipoLista = record Primeiro : Apontador; Último : Apontador; end; UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementaçao: FLVazia, Vazia, Insere procedure FLVazia(var Lista: TipoLista); begin new(Lista.Primeiro); Lista.Último := Lista.Primeiro; Lista.Primeiro^.Prox := nil; end; {FLVazia} function Vazia(Lista: TipoLista): boolean; begin Vazia := Lista.Primeiro = Lista.Último; end; {Vazia} procedure Insere(x: TipoItem; var Lista: TipoLista); begin new(Lista.Último^.Prox); Lista.Último := Lista.Último^.Prox; Lista.Último^.Item := x; Lista.Último^.Prox := nil; end; {Insere} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação: Retira procedure Retira(p: Apontador; var Lista: TipoLista; var Item: TipoItem); {Observação: o item a ser retirado é o seguinte ao apontado por p} var q: Apontador; begin if Vazia(Lista) or (p = nil) or (p^.Prox = nil) then writeln(’Erro: Lista vazia ou posição não existe’) else begin q := p^.Prox; Item := q^.Item; p^.Prox := q^.Prox; if p^.Prox = nil then Lista.último := p; dispose(q); end; end; {Retira} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação: Imprime procedure Imprime(Lista: TipoLista); var Aux: Apontador; begin Aux := Lista.Primeiro^.Prox; while Aux <> nil do begin writeln(Aux^.Item.Chave); Aux := Aux^.Prox; end; end; {Imprime} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Vantagens e desvantagens da implementação de listas através de apontadores • Vantagens: – Permite inserir ou retirar itens do meio da lista a um custo constante. – Aspecto importante quando a lista tem que ser mantida em ordem. – Em aplicações em que não existe previsão sobre o crescimento da lista é conveniente usar listas encadeadas por apontadores, porque neste caso o tamanho máximo da lista não precisa ser definido a priori. • Desvantagem: – A maior desvantagem deste tipo de implementação é a utilização de me- mória extra para armazenar os apontadores. UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Algumas Considerações • Quando escolher listas implementadas com apontadores? – Se o tamanho das listas varia de forma totalmente imprevisível, então a escolha deve cair sobre implementação de apontadores. • Deve-se procurar implementar um programa de forma independente de estru- turas de dados específicas. – Neste caso, deve-se poder trocar a implementação do tipo de dados abs- tratos Lista de apontador para arranjo, bastando trocar a definição dos tipos no programa. • Isto mostra a importância em escrever programas em função das operações para manipular tipos abstratos de dados ao invés de utilizar detalhes particu- lares de implementação. UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Pilhas • Uma pilha é uma lista linear em que todas as inserções, retiradas e, geral- mente, todos os acessos são feitos em apenas um extremo da lista. • Os itens em uma pilha estão colocados um sobre o outro, com o item inserido mais recentemente no topo e o item inserido menos recentemente no fundo. • Exemplo: – Um modelo intuitivo de uma pilha é o de um monte de pratos em uma prateleira. – Esta imagem está frequentemente associada com a teoria do autômato, onde o topo de uma pilha é considerado como o receptáculo de uma cabe- ça de leitura/gravação que pode empilhar e desempilhar itens da pilha. (Este aspecto será estudado na disciplina Fundamentos da Teoria da Com- putação.) UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Pilhas • Propriedade: – O último item inserido é o primeiro item que pode ser retirado da lista. – LIFO: Last-In-First-Out • Aplicações: – Processamento de estruturas aninhadas de profundidade imprevisível, co- mo ? Controle de seqüências de chamadas de subprogramas ? Sintaxe de expressões aritméticas – Recursividade – Árvores UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Conjunto de operações associado ao TAD pilha 1. FPVazia(Pilha) – Faz a pilha ficar vazia. 2. Vazia(Pilha) – Esta função retorna true se a pilha está vazia; senão retorna false. 3. Empilha(x, Pilha) – Insere o item x no topo da pilha. 4. Desempilha(Pilha, x) – Retorna o item x no topo da pilha, retirando-o da pilha. 5. Tamanho(Pilha) – Esta função retorna o número de itens da pilha. UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de pilhas As duas representações mais utilizadas são: 1. Implementações através de arranjos. 2. Implementações através de apontadores. UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de pilhas através de arranjos x1 ... xn ... 1 = Primeiro 2x2 MaxTam Topo • O campo Item é o principal componente do registro TipoPilha • Os itens são armazenados em um arranjo de tamanho suficiente para arma- zenar a pilha • O outro campo do mesmo registro contém um apontador para o item no topo da pilha • A constante MaxTamdefine o tamanho máximo permitido para a pilha UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Estrutura da pilha usando arranjo const MaxTam = 1000; type Apontador = integer; TipoItem = record Chave : TipoChave; {outros componentes} end; TipoPilha = record Item : array[1..MaxTam] of TipoItem; Topo : Apontador; end; UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação: FPVazia, Vazia, Tamanho procedure FPVazia(var Pilha: TipoPilha); begin Pilha.Topo := 0; end; {FPVazia} function Vazia(var Pilha: TipoPilha): boolean; begin Vazia := Pilha.Topo = 0; end; {Vazia} function Tamanho(var Pilha : TipoPilha) : integer; begin Tamanho := Pilha.Topo; end; {Tamanho} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação: Empilha, Desempilha procedure Empilha(x : TipoItem; var Pilha : TipoPilha); begin if Pilha.Topo = MaxTam then writeln(’Erro: Pilha está cheia’) else begin Pilha.Topo := Pilha.Topo + 1; Pilha.Item[Pilha.Topo] := x; end; end; {Empilha} procedure Desempilha (var Pilha : TipoPilha; var Item : TipoItem); begin if Vazia(Pilha) then writeln(’Erro: Pilha está vazia’) else begin Item := Pilha.Item[Pilha.Topo]; Pilha.Topo := Pilha.Topo - 1; end; end; {Desempilha} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Comentários sobre implementação de pilhas através de apontadores • Célula cabeça é mantida no topo da pilha para facilitar a implementação das operações empilha e desempilha quando a pilha está vazia • Para desempilhar o item xn basta desligar a célula cabeça da lista e a célula que contém xn passa a ser a célula cabeça • Para empilhar um novo item basta fazer a operação contrária, criando uma nova célula cabeça e colocando o novo item na antiga célula cabeça • O campo Tamanho existe no registro TipoPilha por questões de eficiência, para evitar a contagem do número de itens da pilha na função Tamanho • Cada célula de uma pilha contém um item da pilha e um apontador para outra célula • O registro TipoPilha contém um apontador para o topo da pilha (célula cabeça) e um apontador para o fundo da pilha UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de pilhas através de apontadores 6 6 @@@@ 6 6 x1 nil xn ... Fundo→ Topo→ Cabeça UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Estrutura da pilha usando apontadores type Apontador = ^Célula; TipoItem = record Chave : TipoChave; {outros componentes} end; Célula = record Item : TipoItem; Prox : Apontador; end; TipoPilha = record Fundo : Apontador;Topo : Apontador; Tamanho : integer; end; UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação: FPVazia, Vazia, Tamanho procedure FPVazia(var Pilha : TipoPilha); begin new(Pilha.Topo); Pilha.Fundo := Pilha.Topo; Pilha.Topo^.Prox := nil; Pilha.Tamanho := 0; end; {FPVazia} function Vazia(var Pilha : TipoPilha) : boolean; begin Vazia := Pilha.Topo = Pilha.Fundo; end; {Vazia} function Tamanho(var Pilha : TipoPilha) : integer; begin Tamanho := Pilha.Tamanho; end; {Tamanho} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação: Empilha, Desempilha procedure Empilha(x: TipoItem; var Pilha : TipoPilha); var Aux : Apontador; begin new(Aux); Pilha.Topo^.Item := x; Aux^.Prox := Pilha.Topo; Pilha.Topo := Aux; Pilha.Tamanho := Pilha.Tamanho + 1; end; {Empilha} procedure Desempilha(var Pilha : TipoPilha, var item : TipoItem); var q : Apontador; begin if Vazia(pilha) then writeln(’Erro: Pilha vazia’) else begin q := Pilha.Topo; Pilha.Topo := q^.Prox; Item := q^.Prox^.Item; dispose(q); Pilha.Tamanho := Pilha.Tamanho - 1; end; end; {Desempilha} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Exemplo: Editor de Textos (ET) • Um ET é um programa que edita um texto baseado em comandos • Em geral, os editores de texto podem ser classificados em editores de linha e editores gráficos • Também é comum haver programas que fazem a edição e formatação do texto de forma conjunta • Para usar um ET é necessário conhecer seus comandos UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Comandos do ET Proposto • Cancela caractere: # – Ação: cancela o caractere anterior na linha que está sendo editada – Para a entrada UEM##FBM##MGtemos a saída UFMG • Cancela linha: \ – Ação: cancela todos os caracteres anteriores na linha que está sendo edi- tada UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Comandos do ET Proposto • Salta linha: @ – Ação: causa a impressão dos caracteres que pertencem à linha que está sendo editada, iniciando uma nova linha de impressão a partir do caractere imediatamente seguinte ao caractere salta linha – Para a entrada DCC@UFMG@temos a saída DCC UFMG • Fim do texto: ~ – Ação: indica o fim do texto UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de um Editor de Textos • Objetivo: – Escrever um editor de texto que aceite os comandos: 1. #: cancela caractere 2. \ : cancela linha 3. @: salta linha 4. ~: fim do texto • O ET deverá ler um caractere de cada vez do texto de entrada e produzir a impressão linha a linha, cada linha contendo no máximo 70 caracteres de impressão. UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de um Editor de Textos • O ET deverá utilizar o tipo abstrato de dados Pilha, implementado através de arranjo • Observações: – O programa deve utilizar um TAD sem conhecer detalhes de sua implemen- tação – Isto significa que a implementação do TAD Pilha que utiliza arranjo pode ser substituída pela implementação que utiliza apontadores sem causar impacto no programa UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Sugestão para Testar o Programa ET Este et# um teste para o ET, o extraterrestre em PASCAL.@Acabamos de testar a capacidade do ET saltar de linha, utilizando seus poderes extras (cuidado pois agora vamos estourar a capacidade máxima da linha de impressão, que é de setenta caracteres).@O k#cut#rso dh#e Estruturas de Dados et# h#um cuu#rsh#o #x# x?*!#?!##+.@ Como et# bom n#nt#ao### r#ess#tt#ar mb#aa#triz#cull#ado nn#x#ele!\Será que este funciona\\\? O sinal? deve não### deve ficar!~ UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação do ET program ET; const MaxTam = 70; CancelaCaractere = ’#’; CancelaLinha = ’\’; SaltaLinha = ’@’; MarcaEof = ’~’; type TipoChave = char; {Incluir aqui os tipos definidos para implementação de Pilha com arranjo} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação do ET var Pilha : TipoPilha; x : TipoItem; {Incluir aqui os procedimentos FPVazia, Vazia, Tamanho, Empilha, Desempilha} procedure Imprime(var Pilha : TipoPilha); var Pilhaux : TipoPilha; x : TipoItem; begin FPVazia(Pilhaux); while not Vazia(Pilha) do begin Desempilha(Pilha, x); Empilha(x, Pilhaux); end; while not Vazia(Pilhaux) do begin Desempilha(Pilhaux, x); write(x.Chave); end; writeln; end; UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação do ET begin FPVazia(Pilha); read(x, Chave); while x.Chave <> MarcaEof do begin if x.Chave = CancelaCaractere then begin if not Vazia(Pilha) then Desempilha(Pilha, x) end else if x.Chave = CancelaLinha then FPVazia(Pilha) else if x.Chave = SaltaLinha then Imprime(Pilha) else begin if Tamanho(Pilha) = MaxTam then Imprime(Pilha); Empilha(x, Pilha); end; read(x.Chave); end; if not Vazia(Pilha) then Imprime(Pilha); end. UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Filas • Uma fila é uma lista linear em que todas as inserções são realizadas em um extremo da lista, e todas as retiradas e, geralmente os acessos, são realiza- dos no outro extremo da lista • Modelo Intuitivo: – Fila de espera em que as pessoas no início da fila são servidas primeiro e as pessoas que chegam entram no fim da fila – Ordem linear para filas: ordem de chegada UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Filas • Propriedade: – O primeiro item inserido é o primeiro item que pode ser retirado da lista – FIFO: First-In-First-Out • Aplicações: – Filas são utilizadas quando desejamos processar itens de acordo com a ordem do “primeiro que chega é o primeiro a ser atendido” – Sistemas operacionais utilizam filas para regular a ordem na qual tarefas devem receber processamento e recursos devem ser alocados a processos UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Conjunto de operações associado ao TAD Fila 1. FFVazia(Fila) – Faz a fila ficar vazia 2. Enfileira(x, Fila) – Insere o item x no final da fila 3. Desenfileira(Fila, x) – Retorna o item x no início da fila, retirando-o da fila 4. Vazia(Fila) – Esta função retorna true se a fila está vazia; senão retorna false UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de filas através de arranjos • Dada as características da fila: – Enfileria faz a parte de trás da fila expandir-se – Desenfileira faz a parte da frente da fila contrair-se • Conseqüência: – A fila tende a “caminhar” pela memória do computador, ocupando espaço na parte de trás e descartando espaço na parte da frente – Com poucas inserções e retiradas de itens a fila vai de encontro ao limite do espaço da memória alocado por ela • Solução: – Imaginar um arranjo como um círculo, onde a primeira posição segue a última UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de filas através de arranjos • Enfileirar um item: – Basta mover o apontador trás uma posição no sentido horário • Desenfileirar um item: – Basta mover o apontador frente uma posição no sentido horário UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Problema associado com a representação circular • Não há forma de distinguir uma fila vazia de uma fila cheia. ➜ Nos dois casos os apontadores Frente e Trás apontam para a mesma posição no círculo • Possível solução: – Não usar todo o espaço do arranjo, deixando uma posição vazia • Fila cheia: Trás + 1 = Frente – Existe uma célula vazia entre o fim e o início da fila UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação circular para filas • Item: – Principal componente do registro TipoFila • MaxTam: – Tamanho máximo do arranjo circular • TipoFila: – Contêm apontadores para a parte da frente e de trás da fila UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Estrutura da fila usando arranjo const MaxTam = 1000; type Apontador = integer; TipoItem = record Chave : TipoChave; {outros componentes} end; TipoFila = record Item : array[1..MaxTam] of TipoItem; Frente : Apontador; Trás : Apontador; end; UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Operações sobre filas usando posições contíguas de memória: FFVazia, Vazia procedure FFVazia(var Fila: TipoFila); begin Fila.Frente := 1; Fila.Trás := Fila.Frente; end; {FFVazia} function Vazia(var Fila: TipoFila) : boolean; beginVazia := Fila.Frente = Fila.Trás; end; {Vazia} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Operações sobre filas usando posições contíguas de memória: Enfileira, Desenfileira procedure Enfileira(x: TipoItem; var Fila : TipoFila); begin if Fila.Trás mod MaxTam + 1 = Fila.Frente then writeln(’Erro: Fila está cheia’) else begin Fila.Item[Fila.Trás] := x; Fila.Trás := Fila.Trás mod MaxTam + 1; end; end; {Enfileira} procedure Desenfileira(var Fila : TipoFila; var Item : TipoItem); begin if Vazia(Fila) then writeln(’Erro: Fila está vazia’) else begin Item := Fila.Item[Fila.Frente]; Fila.Frente := Fila.Frente mod MaxTam + 1; end; end; {Desenfileira} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Implementação de filas através de apontadores • Célula Cabeça: – Mantida para facilitar a implementação das operações Enfileira e Desenfi- leira quando a fila está vazia – Quando a fila está vazia os apontadores Frente e Trás apontam para a célula cabeça • Para enfileirar um novo item: – Cria uma célula nova – Insere após a célula que contém xn – Atribui a nova célula o item • Para desenfileirar o item x1: – Desliga a célula cabeça da lista – A célula que contém x1 passa a ser a célula cabeça UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Estrutura da fila usando apontadores -- - -@@@@ 6 6 x1 xn nilLista . . . Frente Trás type Apontador = ^Célula; TipoItem = record Chave : TipoChave; {outros componentes} end; Célula = record Item : TipoItem; Prox : Apontador; end; TipoItem = record Frente: Apontador; Trás: Apontador; end; UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Operações sobre filas usando apontadores: FFVazia, Vazia procedure FFVazia (var Fila : TipoFila); begin new(Fila.Frente); Fila.Trás := Fila.Frente; Fila.Frente^.Prox := vil; end; {FFVazia} fuction Vazia(var Fila : TipoFila) : boolean; begin Vazia := Fila.Frente = Fila.Trás; end; {Vazia} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Operações sobre filas usando apontadores: Enfileira, Desenfileira procedure Enfileira (x: TipoItem; var Fila : TipoFila); begin new(Fila.Trás^.Prox); Fila.Trás := Fila.Trás^.Prox; Fila.Trás^.Item := x; Fila.Trás^.Prox := nil; end; {Enfileira} procedure Desenfileira(Var Fila : TipoFila; varItem : TipoItem); var q : Apontador; begin if Vazia(Fila) then writeln(’Erro: Fila está vazia’) else begin q := Fila.Frente; Fila.Frente := Fila.Frente^.Prox; Item := Fila.Frente^.Item; dispose(q); end; end; {Desenfileira} UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Listas duplamente encadeadas • Listas lineares simples – Movimento somente na direção dos apontadores • Única forma de encontrar item que precede P – Começar novamente no início da lista • Mesmo problema ocorre para remoção. – Solução: Listas Duplamente Encadeadas UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Listas duplamente encadeadas - � - � • Uma célula em uma lista duplamente encadeada possui no mínimo três cam- pos: – item – apontador para a célula da esquerda – apontador para a célula da direita UFMG/ICEx/DCC AEDS2/2◦ Semestre de 2002 Listas duplamente encadeadas • Uma lista duplamente encadeada pode ser circular como no seguinte exemplo • Suponha que P aponte para uma célula em uma lista duplamente encadeada P = Dir(Esq(P)) = Esq(Dir(P)) ➜ Esta fórmula reflete o ponto mais importante desta estrutura, ou seja, po- demos caminhar para frente e para trás com a mesma facilidade em uma lista deste tipo • Exemplo de uma lista duplamente encadeada vazia:
Compartilhar