Você está na página 1de 13

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.

1 1

Listas Lineares

• Uma das formas mais simples de interligar os


elementos de um conjunto.

• Estrutura em que as operações inserir, retirar


e localizar são definidas.

Estruturas de Dados • Podem crescer ou diminuir de tamanho


durante a execução de um programa, de
Básicas∗ acordo com a demanda.

• Itens podem ser acessados, inseridos ou


retirados de uma lista.

• Duas listas podem ser concatenadas para


formar uma lista única, ou uma pode ser
partida em duas ou mais listas.

• Adequadas quando não é possível prever a


demanda por memória, permitindo a
Última alteração: 26 de Março de 2004
manipulação de quantidades imprevisíveis de
dados, de formato também imprevisível.

• São úteis em aplicações tais como


manipulação simbólica, gerência de memória,
∗ Transparências
simulação e compiladores.
elaboradas por Charles Ornelas Almeida e Nivio Ziviani

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1 2 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1 3

Definição de Listas Lineares TAD Listas Lineares

• Seqüência de zero ou mais itens • O conjunto de operações a ser definido


x1 , x2 , · · · , xn , na qual xi é de um determinado depende de cada aplicação.
tipo e n representa o tamanho da lista linear. • Um conjunto de operações necessário a uma
maioria de aplicações é:
• Sua principal propriedade estrutural envolve
as posições relativas dos itens em uma 1. Criar uma lista linear vazia.
dimensão. 2. Inserir um novo item imediatamente após
o i-ésimo item.
– Assumindo n ≥ 1, x1 é o primeiro item da
lista e xn é o último item da lista. 3. Retirar o i-ésimo item.

– xi precede xi+1 para i = 1, 2, · · · , n − 1 4. Localizar o i-ésimo item para examinar


e/ou alterar o conteúdo de seus
– xi sucede xi−1 para i = 2, 3, · · · , n
componentes.
– o elemento xi é dito estar na i-ésima 5. Combinar duas ou mais listas lineares em
posição da lista. 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 componente.
Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1 4 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.1 5

Implementações de Listas Lineares Implementação de Listas por meio de


Arranjos
• Várias estruturas de dados podem ser usadas
para representar listas lineares, cada uma • Os itens da lista são armazenados em
com vantagens e desvantagens particulares. posições contíguas de memória.
• A lista pode ser percorrida em qualquer
• As duas representações mais utilizadas são
direção.
as implementações por meio de arranjos e de
apontadores. • A inserção de um novo item pode ser
realizada após o último item com custo
• Exemplo de Conjunto de Operações:
constante.
1. FLVazia(Lista). Faz a lista ficar vazia.
• A inserção de um novo item no meio da lista
2. Insere(x, Lista). Insere x após o último requer um deslocamento de todos os itens
item da lista. localizados após o ponto de inserção.
3. Retira(p, Lista, x). Retorna o item x que • Retirar um item do início da lista requer um
está na posição p da lista, retirando-o da deslocamento de itens para preencher o
lista e deslocando os itens a partir da espaço deixado vazio.
posição p+1 para as posições anteriores.
Itens
4. Vazia(Lista). Esta função retorna true se Primeiro = 1 x1
lista vazia; senão retorna false. 2 x2
..
5. Imprime(Lista). Imprime os itens da lista .
na ordem de ocorrência. Último−1 xn
..
.
MaxTam

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.1 6 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.1 7

Estrutura da Lista Usando Arranjo Operações sobre Lista Usando Arranjo


• Os itens são armazenados em um array de procedure FLVazia ( var Lista : TipoLista ) ;
tamanho suficiente para armazenar a lista. begin
• O campo Último aponta para a posição Lista . Primeiro : = InicioArranjo ;

seguinte a do último elemento da lista. Lista . Ultimo : = Lista . Primeiro ;


end;
• O i-ésimo item da lista está armazenado na
i-ésima posição do array, 1 ≤ i <Último. function Vazia ( var Lista : TipoLista ) : boolean;
• A constante MaxTam define o tamanho begin

máximo permitido para a lista. Vazia : = Lista . Primeiro = Lista . Ultimo ;


end;
const
InicioArranjo = 1; procedure Insere ( x : TipoItem ; var Lista : TipoLista ) ;
MaxTam = 1000; begin
type i f Lista . Ultimo > MaxTam
TipoChave = integer ; then writeln ( ’ Lista esta cheia ’ )
Apontador = integer ; else begin
TipoItem = record Lista . Item [ Lista . Ultimo ] : = x ;
Chave: TipoChave; Lista . Ultimo : = Lista . Ultimo + 1;
{ outros componentes } end;
end; end;
TipoLista = record
Item : array [ 1 . .MaxTam] of TipoItem ;
Primeiro : Apontador;
Ultimo : Apontador
end;
Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.1 8 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.1 9

Operações sobre Lista Usando Arranjo Lista Usando Arranjo - Vantagens e


Desvantagens
procedure Retira (p:Apontador ; var Lista : TipoLista ;
var Item : TipoItem ) ; • Vantagem: economia de memória (os
var Aux: integer ; apontadores são implícitos nesta estrutura).
begin
i f Vazia ( Lista ) or (p >= Lista . Ultimo) • Desvantagens:
then writeln ( ’ Erro : Posicao nao existe ’ ) – custo para inserir ou retirar itens da lista,
else begin que pode causar um deslocamento de
Item : = Lista . Item [p ] ; todos os itens, no pior caso;
Lista . Ultimo : = Lista . Ultimo − 1;
– em aplicações em que não existe previsão
for Aux : = p to Lista . Ultimo − 1 do
Lista . Item [Aux] : = Lista . Item [Aux+1]; sobre o crescimento da lista, a utilização
end; de arranjos em linguagens como o Pascal
end; pode ser problemática porque neste caso
o tamanho máximo da lista tem de ser
procedure Imprime ( var Lista : TipoLista ) ; definido em tempo de compilação.
var Aux: integer ;
begin
for Aux : = Lista . Primeiro to Lista . Ultimo − 1 do
writeln ( Lista . Item [Aux] .Chave) ;
end;

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 10 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 11

Implementação de Listas por meio de Estrutura da Lista Usando


Apontadores Apontadores

• Cada item é encadeado com o seguinte • A lista é constituída de células.


mediante uma variável do tipo Apontador. • Cada célula contém um item da lista e um
• Permite utilizar posições não contíguas de apontador para a célula seguinte.
memória. • O registro TipoLista contém um apontador
para a célula cabeça e um apontador para a
• É possível inserir e retirar elementos sem
última célula da lista.
necessidade de deslocar os itens seguintes
da lista. type
Apontador = ^Celula ;
• Há uma célula cabeça para simplificar as
TipoItem = record
operações sobre a lista.
Chave: TipoChave;
{ outros componentes }
Lista x1 ... xn nil end;
Celula = record
Item : TipoItem ;
Prox : Apontador;
end;
TipoLista = record
Primeiro : Apontador;
Ultimo : Apontador;
end;
Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 12 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 13

Operações sobre Lista Usando Operações sobre Lista Usando


Apontadores Apontadores

procedure FLVazia ( var Lista : TipoLista ) ; procedure Retira (p:Apontador ; var Lista : TipoLista ;
begin var Item : TipoItem ) ;
new ( Lista . Primeiro ) ; {−−Obs. : o item a ser retirado e
Lista . Ultimo : = Lista . Primeiro ; o seguinte ao apontado por p −−}
Lista . Primeiro^.Prox : = n i l ; var q : Apontador;
end; begin
i f Vazia ( Lista ) or (p = n i l ) or (p^.Prox = n i l )
then writeln ( ’ Erro : Lista vazia ou posicao nao existe ’ )
function Vazia ( Lista : TipoLista ) : boolean;
else begin
begin
q : = p^.Prox ; Item : = q^.Item ; p^.Prox : = q^.Prox;
Vazia : = Lista . Primeiro = Lista . Ultimo ;
i f p^.Prox = n i l then Lista . Ultimo : = p;
end;
dispose (q) ;
end;
procedure Insere ( x : TipoItem ; var Lista : TipoLista ) ;
end;
begin
new( Lista . Ultimo^.Prox ) ;
procedure Imprime ( Lista : TipoLista ) ;
Lista . Ultimo : = Lista . Ultimo^.Prox;
var Aux: Apontador;
Lista . Ultimo^.Item : = x ;
begin
Lista . Ultimo^.Prox : = n i l
Aux : = Lista . Primeiro^.Prox;
end;
while Aux <> n i l do
begin
writeln (Aux^.Item .Chave) ; Aux : = Aux^.Prox;
end;
end;

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 14 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 15

Listas Usando Apontadores - Exemplo de Uso Listas - Vestibular


Vantagens e Desvantagens
• Num vestibular, cada candidato tem direito a
• Vantagens: três opções para tentar uma vaga em um dos
– Permite inserir ou retirar itens do meio da sete cursos oferecidos.
lista a um custo constante (importante • Para cada candidato é lido um registro:
quando a lista tem de ser mantida em
– Chave: número de inscrição do candidato.
ordem).
– NotaFinal: média das notas do candidato.
– Bom para aplicações em que não existe
previsão sobre o crescimento da lista (o – Opção: vetor contendo a primeira, a
tamanho máximo da lista não precisa ser segunda e a terceira opções de curso do
definido a priori). candidato.

• Desvantagem: utilização de memória extra Chave : 1..999;

para armazenar os apontadores. NotaFinal : 0..10;


Opcao : array [ 1 . . 3 ] of 1 . . 7 ;

• Problema: distribuir os candidatos entre os


cursos, segundo a nota final e as opções
apresentadas por candidato.

• Em caso de empate, os candidatos serão


atendidos na ordem de inscrição para os
exames.
Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 16 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 17

Vestibular - Possível Solução Vestibular - Classificação dos Alunos


• ordenar registros pelo campo NotaFinal, • Uma boa maneira de representar um conjunto
respeitando a ordem de inscrição; de registros é com o uso de listas.
• percorrer cada conjunto de registros com
• Ao serem lidos, os registros são
mesma NotaFinal, começando pelo conjunto
armazenados em listas para cada nota.
de NotaFinal 10, seguido pelo de NotaFinal 9,
e assim por diante. • Após a leitura do último registro os candidatos
– Para um conjunto de mesma NotaFinal estão automaticamente ordenados por
tenta-se encaixar cada registro desse NotaFinal.
conjunto em um dos cursos, na primeira • Dentro de cada lista, os registros estão
das três opções em que houver vaga (se
ordenados por ordem de inscrição, desde que
houver).
os registros sejam lidos na ordem de inscrição
• Primeiro refinamento: de cada candidato e inseridos nesta ordem.
NotaFinal
program Vestibular ;
0
begin

...
ordena os registros pelo campo NotaFinal ;
for Nota := 10 downto 0 do
7
while houver registro com mesma nota do 8 ...
i f existe vaga em um dos cursos de opcao do candidato 9 Registro nil
then insere registro no conjunto de aprovados 10 Registro Registro nil
else insere registro no conjunto de reprovados;
imprime aprovados por curso ; imprime reprovados;
end.

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 18 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 19

Vestibular - Classificação dos Alunos Vestibular - Segundo Refinamento

• As listas de registros são percorridas, program Vestibular;


iniciando-se pela de NotaFinal 10, seguida begin
lê número de vagas para cada curso;
pela de NotaFinal 9, e assim sucessivamente.
inicializa listas de classificação de aprovados e reprovados;
• Cada registro é retirado e colocado em uma lê registro;
das listas da abaixo, na primeira das três while Chave <> 0 do
opções em que houver vaga. begin

Cursos
insere registro nas listas de classificação, conforme nota final;

Registro Registro ... lê registro;


1
Registro ... end;
2
3 ... for Nota := 10 downto 0 do
4 while houver próximo registro com mesma NotaFinal do
5 begin
6 retira registro da lista;
7 if existe vaga em um dos cursos de opção do candidato
then begin
• Se não houver vaga, o registro é colocado em insere registro na lista de aprovados;
uma lista de reprovados. decrementa o número de vagas para aquele curso;
end
• Ao final a estrutura acima conterá a relação
else insere registro na lista de reprovados;
de candidatos aprovados em cada curso. obtém próximo registro;
end;
imprime aprovados por curso;
imprime reprovados;
end.
Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 20 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 21

Vestibular - Estrutura Final da Lista Vestibular - Refinamento Final

const NOpcoes = 3; NCursos = 7; • Observe que o programa é completamente


type independente da implementação do tipo
TipoChave = 1..999; abstrato de dados Lista.
TipoItem = record
Chave: TipoChave; program Vestibular ;
NotaFinal : 0..10; {−− Entram aqui os tipos da transparência 20−−}
Opcao: array [ 1 . .NOpcoes] of 1 . .NCursos; var Registro : TipoItem ;
end; Classificacao : array [ 0 . . 1 0 ] of TipoLista ;
Apontador = ^Celula ; Aprovados : array [ 1 . .NCursos] of TipoLista ;
Celula = record Reprovados : TipoLista ;
Item : TipoItem ; Vagas : array [ 1 . .NCursos] of integer ;
Prox : Apontador; Passou : boolean;
end; i , Nota : integer ;
TipoLista = record {−− Entram aqui as operações sobre listas usando
Primeiro : Apontador; apontadores das transparências 12 e 13−−}
Ultimo : Apontador; {−− Entra aqui o procedimento LeRegistro ( transp . 20) −−}
end; begin {−− Programa principal −−}
procedure LeRegistro ( var Registro : TipoItem ) ; for i := 1 to NCursos do read (Vagas[ i ] ) ; readln;
{−−−os valores lidos devem estar separados por brancos−−−} for i := 0 to 10 do FLVazia ( Classificacao [ i ] ) ;
var i : integer ; for i := 1 to NCursos do FLVazia (Aprovados[ i ] ) ;
begin FLVazia (Reprovados) ; LeRegistro ( Registro ) ;
read ( Registro .Chave, Registro . NotaFinal ) ; while Registro .Chave <> 0 do
for i := 1 to NOpcoes do read ( Registro .Opcao[ i ] ) ; begin
readln; Insere ( Registro , Classificacao [ Registro . NotaFinal ] ) ;
end; LeRegistro ( Registro ) ;
end;

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 22 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.1.2 23

Vestibular - Refinamento Final (Cont.) Vestibular - Refinamento Final (Cont.)

for Nota := 10 downto 0 do for i := 1 to NCursos do


while not Vazia ( Classificacao [Nota ] ) do begin
begin writeln ( ’Relacao dos aprovados no Curso ’ , i : 2 ) ;
Retira ( Classificacao [Nota ] . Primeiro , Imprime (Aprovados[ i ] ) ;
Classificacao [Nota] , Registro ) ; end;
i : = 1 ; Passou : = false ; writeln ( ’Relacao dos reprovados ’ ) ;
while ( i <= NOpcoes) and not Passou do Imprime (Reprovados) ;
begin end.
i f Vagas[ Registro .Opcao[ i ]] > 0
then begin • O exemplo mostra a importância de utilizar
Insere ( Registro , tipos abstratos de dados para escrever
Aprovados[ Registro .Opcao[ i ] ] ) ; programas, em vez de utilizar detalhes
Vagas[ Registro .Opcao[ i ] ] : =
particulares de implementação.
Vagas[ Registro .Opcao[ i ]] − 1;
Passou : = true ; • Altera-se a implementação rapidamente. Não
end; é necessário procurar as referências diretas
i : = i + 1; às estruturas de dados por todo o código.
end;
i f not Passou then Insere ( Registro , Reprovados) ; • Este aspecto é particularmente importante
end; em programas de grande porte.
Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2 24 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2 25

Pilha Propriedade e Aplicações das Pilhas

• É uma lista linear em que todas as inserções, • Propriedade: o último item inserido é o
retiradas e, geralmente, todos os acessos são primeiro item que pode ser retirado da lista.
feitos em apenas um extremo da lista. São chamadas listas lifo (“last-in, first-out”).
• Existe uma ordem linear para pilhas, do “mais
• Os itens são colocados um sobre o outro. O
recente para o menos recente”.
item inserido mais recentemente está no topo
e o inserido menos recentemente no fundo. • É ideal para processamento de estruturas
aninhadas de profundidade imprevisível.
• O modelo intuitivo é o de um monte de pratos
em uma prateleira, sendo conveniente retirar • Uma pilha contém uma seqüência de
ou adicionar pratos na parte superior. obrigações adiadas. A ordem de remoção
garante que as estruturas mais internas serão
• Esta imagem está freqüentemente associada processadas antes das mais externas.
com a teoria de autômato, na qual o topo de
• Aplicações em estruturas aninhadas:
uma pilha é considerado como o receptáculo
de uma cabeça de leitura/gravação que pode – Quando é necessário caminhar em um
conjunto de dados e guardar uma lista de
empilhar e desempilhar itens da pilha.
coisas a fazer posteriormente.
– O controle de seqüências de chamadas de
subprogramas.
– A sintaxe de expressões aritméticas.
• As pilhas ocorrem em estruturas de natureza
recursiva (como árvores). Elas são utilizadas
para implementar a recursividade.

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2 26 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.1 27

TAD Pilhas Implementação de Pilhas por meio de


Arranjos
• Conjunto de operações:
1. FPVazia(Pilha). Faz a pilha ficar vazia. • Os itens da pilha são armazenados em
posições contíguas de memória.
2. Vazia(Pilha). Retorna true se a pilha está
vazia; caso contrário, retorna false. • Como as inserções e as retiradas ocorrem no
3. Empilha(x, Pilha). Insere o item x no topo topo da pilha, um cursor chamado Topo é
da pilha. utilizado para controlar a posição do item no
topo da pilha.
4. Desempilha(Pilha, x). Retorna o item x no
topo da pilha, retirando-o da pilha. Itens
Primeiro = 1 x1
5. Tamanho(Pilha). Esta função retorna o 2 x2
número de itens da pilha. ..
.
• Existem várias opções de estruturas de Topo xn
dados que podem ser usadas para ..
.
representar pilhas. MaxTam

• As duas representações mais utilizadas são


as implementações por meio de arranjos e de
apontadores.
Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.1 28 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.1 29

Estrutura da Pilha Usando Arranjo Operações sobre Pilhas Usando


Arranjos
• Os itens são armazenados em um array de
tamanho suficiente para conter a pilha. procedure FPVazia ( var Pilha : TipoPilha ) ;
begin
• O outro campo do mesmo registro contém um
Pilha .Topo := 0;
apontador para o item no topo da pilha. end;

• A constante MaxTam define o tamanho


function Vazia ( var Pilha : TipoPilha ) : boolean;
máximo permitido para a pilha.
begin
const MaxTam = 1000; Vazia : = Pilha .Topo = 0;
type end;
TipoChave = integer ;
Apontador = integer ; procedure Empilha ( x : TipoItem ; var Pilha : TipoPilha ) ;
TipoItem = record begin
Chave: TipoChave; i f Pilha .Topo = MaxTam
{ outros componentes } then writeln ( ’ Erro : pilha esta cheia ’ )
end; else begin
TipoPilha = record Pilha .Topo : = Pilha .Topo + 1;
Item : array [ 1 . .MaxTam] of TipoItem ; Pilha . Item [ Pilha .Topo] : = x ;
Topo: Apontador; end;
end; end;

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.1 30 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.2 31

Operações sobre Pilhas Usando Implementação de Pilhas por meio de


Arranjos Apontadores

procedure Desempilha ( var Pilha : TipoPilha ; • Há uma célula cabeça é no topo para facilitar
var Item : TipoItem ) ; a implementação das operações empilha e
begin desempilha quando a pilha está vazia.
i f Vazia ( Pilha )
• Para desempilhar o item xn basta desligar a
then writeln ( ’ Erro : pilha esta vazia ’ )
célula cabeça da lista e a célula que contém
else begin
xn passa a ser a célula cabeça.
Item : = Pilha . Item [ Pilha .Topo] ;
Pilha .Topo : = Pilha .Topo − 1; • Para empilhar um novo item, basta fazer a
end; operação contrária, criando uma nova célula
end; cabeça e colocando o novo item na antiga.
nil
function Tamanho ( Pilha : TipoPilha ) : integer ;
6
begin
Fundo - x1
Tamanho : = Pilha .Topo;
end; 6
..
.
6
xn

Topo -
Cabeça
Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.2 32 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.2 33

Estrutura da Pilha Usando Operações sobre Pilhas Usando


Apontadores Apontadores
• O campo Tamanho evita a contagem do procedure FPVazia ( var Pilha : TipoPilha ) ;
número de itens na função Tamanho. begin
new ( Pilha .Topo) ;
• Cada célula de uma pilha contém um item da
Pilha .Fundo : = Pilha .Topo;
pilha e um apontador para outra célula.
Pilha .Topo^.Prox : = n i l ;
• O registro TipoPilha contém um apontador Pilha .Tamanho := 0;
para o topo da pilha (célula cabeça) e um end;
apontador para o fundo da pilha.
function Vazia ( var Pilha : TipoPilha ) : boolean;
type Apontador = ^Celula ; begin
TipoItem = record Vazia : = Pilha .Topo = Pilha .Fundo;
Chave: TipoChave; end;
{ outros componentes }
end; procedure Empilha ( x : TipoItem ; var Pilha : TipoPilha ) ;
Celula = record var Aux: Apontador;
Item : TipoItem ; begin
Prox : Apontador; new (Aux) ;
end; Pilha .Topo^.Item : = x ;
TipoPilha = record Aux^.Prox : = Pilha .Topo;
Fundo : Apontador; Pilha .Topo : = Aux;
Topo : Apontador; Pilha .Tamanho : = Pilha .Tamanho + 1;
Tamanho: integer ; end;
end;

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.2 34 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.2 35

Operações sobre Pilhas Usando Exemplo de Uso Pilhas - Editor de


Apontadores Textos (ET)

procedure Desempilha ( var Pilha : TipoPilha ; • “#”: cancelar caractere anterior na linha sendo
var Item : TipoItem ) ; editada. Ex.: UEM##FMB#G → UFMG.
var q : Apontador; • “\”: cancela todos os caracteres anteriores na
begin linha sendo editada.
i f Vazia ( Pilha )
then writeln ( ’ Erro : l i s t a vazia ’ ) • “*”: salta a linha. Imprime os caracteres que
else begin pertencem à linha sendo editada, iniciando
q : = Pilha .Topo; uma nova linha de impressão a partir do
Pilha .Topo : = q^.Prox; caractere imediatamente seguinte ao
Item : = q^.Prox^.Item ; caractere salta-linha. Ex: DCC*UFMG.* →
dispose (q) ; DCC
Pilha .Tamanho : = Pilha .Tamanho − 1; UFMG.
end;
• Vamos escrever um Editor de Texto (ET) que
end;
aceite os três comandos descritos acima.
function Tamanho ( Pilha : TipoPilha ) : integer ; • O ET deverá ler um caractere de cada vez do
begin texto de entrada e produzir a impressão linha
Tamanho : = Pilha .Tamanho; a linha, cada linha contendo no máximo 70
end; caracteres de impressão.
• O ET deverá utilizar o tipo abstrato de
dados Pilha definido anteriormente,
implementado por meio de arranjo.
Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.2 36 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.2 37

Sugestão de Texto para Testar o ET ET - Implementação


Este et# um teste para o ET, o extraterrestre em • Este programa utiliza um tipo abstrato de
PASCAL.*Acabamos de testar a capacidade de o ET dados sem conhecer detalhes de sua
saltar de linha, implementação.

utilizando seus poderes extras (cuidado, pois agora • A implementação do TAD Pilha que utiliza
vamos estourar arranjo pode ser substituída pela
a capacidade máxima da linha de impressão, que é de implementação que utiliza apontadores sem
70 causar impacto no programa.

caracteres.)*O k#cut#rso dh#e Estruturas de Dados program ET;


et# h#um const MaxTam = 70;
CancelaCarater = ’# ’ ;
cuu#rsh#o #x# x?*!#?!#+.* Como et# bom
CancelaLinha = ’\ ’;
n#nt#ao### r#ess#tt#ar mb#aa#triz#cull#ado SaltaLinha = ’ \∗ ’ ;
nn#x#ele!\ Sera MarcaEof = ’~ ’ ;
que este funciona\\\? O sinal? não### deve ficar! ~ type TipoChave = char;
{−− Entram aqui os tipos da transparência 28−−}
var
Pilha : TipoPilha ;
x : TipoItem ;
{−− Entram aqui os operadores das transparências
29 e 30−−}
{−− Entra aqui o procedimento Imprime ( transp . 39) −−}

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.2 38 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.2.2 39

ET - Implementação ET - Implementação (Procedimento


Imprime)
begin {−−−Programa principal−−−}
FPVazia ( Pilha ) ; read ( x .Chave) ; procedure Imprime ( var Pilha : TipoPilha ) ;
while x .Chave <> MarcaEof do var Pilhaux : TipoPilha ; x : TipoItem ;
begin begin
i f x .Chave = CancelaCarater FPVazia ( Pilhaux ) ;
then begin while not Vazia ( Pilha ) do
i f not Vazia ( Pilha ) begin
then Desempilha ( Pilha , x ) ; Desempilha ( Pilha , x ) ;
end Empilha ( x , Pilhaux ) ;
else i f x .Chave = CancelaLinha end;
then FPVazia ( Pilha ) while not Vazia ( Pilhaux ) do
else i f x .Chave = SaltaLinha begin
then Imprime ( Pilha ) Desempilha ( Pilhaux , x ) ;
else begin write ( x .Chave) ;
i f Tamanho ( Pilha ) = MaxTam end;
then Imprime ( Pilha ) ; writeln ;
Empilha ( x , Pilha ) ; end;
end;
read ( x .Chave) ;
end;
i f not Vazia ( Pilha ) then Imprime ( Pilha ) ;
end.
Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.3 40 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.3 41

Fila TAD Filas

• É uma lista linear em que todas as inserções • Conjunto de operações:


são realizadas em um extremo da lista, e 1. FFVazia(Fila). Faz a fila ficar vazia.
todas as retiradas e, geralmente, os acessos
2. Enfileira(x, Fila). Insere o item x no final da
são realizados no outro extremo da lista.
fila.
• O modelo intuitivo de uma fila é o de uma fila 3. Desenfileira(Fila, x). Retorna o item x no
de espera em que as pessoas no início da fila início da fila, retirando-o da fila.
são servidas primeiro e as pessoas que
4. Vazia(Fila). Esta função retorna true se a
chegam entram no fim da fila.
fila está vazia; senão retorna false.
• São chamadas listas fifo (“first-in”, “first-out”).

• Existe uma ordem linear para filas que é a


“ordem de chegada”.

• São utilizadas quando desejamos processar


itens de acordo com a ordem
“primeiro-que-chega, primeiro-atendido”.

• Sistemas operacionais utilizam filas para


regular a ordem na qual tarefas devem
receber processamento e recursos devem ser
alocados a processos.

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.3.1 42 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.3.1 43

Implementação de Filas por meio de Implementação de Filas por meio de


Arranjos Arranjos
n 1
• Os itens são armazenados em posições 2 Frente
contíguas de memória. 3
...

• A operação Enfileira faz a parte de trás da fila 4

expandir-se. Tras
´ 8 5
7 6
• A operação Desenfileira faz a parte da frente
• A fila se encontra em posições contíguas de
da fila contrair-se.
memória, em alguma posição do círculo,
• A fila tende a caminhar pela memória do delimitada pelos apontadores Frente e Trás.
computador, ocupando espaço na parte de
• Para enfileirar, basta mover o apontador Trás
trás e descartando espaço na parte da frente.
uma posição no sentido horário.
• Com poucas inserções e retiradas, a fila vai
ao encontro do limite do espaço da memória • Para desenfileirar, basta mover o apontador
alocado para ela. Frente uma posição no sentido horário.

• Solução: imaginar o array como um círculo. A


primeira posição segue a última.
n 1
2 Frente
3
...

4
Tras
´ 8 5
7 6
Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.3.1 44 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.3.1 45

Estrutura da Fila Usando Arranjo Operações sobre Filas Usando


Posições Contíguas de Memória
• O tamanho máximo do array circular é
definido pela constante MaxTam. • Nos casos de fila cheia e fila vazia, os
apontadores Frente e Trás apontam para a
• Os outros campos do registro TipoPilha
mesma posição do círculo.
contêm apontadores para a parte da frente e
de trás da fila. • Uma saída para distinguir as duas situações é
deixar uma posição vazia no array.
const MaxTam = 1000;
type • Neste caso, a fila está cheia quando Trás+1
TipoChave = integer ; for igual a Frente.
Apontador = integer ;
TipoItem = record procedure FFVazia ( var Fila : TipoFila ) ;
Chave: TipoChave; begin
{ outros componentes } Fila . Frente := 1;
end; Fila .Tras := Fila . Frente ;
TipoFila = record end; { FFVazia }
Item : array [ 1 . .MaxTam] of TipoItem ;
Frente : Apontador; function Vazia ( var Fila : TipoFila ) : boolean;
Tras : Apontador; begin
end; Vazia : = Fila . Frente = Fila .Tras;
end;

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.3.1 46 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.3.2 47

Operações sobre Filas Usando Implementação de Filas por meio de


Posições Contíguas de Memória Apontadores
• A implementação utiliza aritmética modular • Há uma célula cabeça é para facilitar a
nos procedimentos Enfileira e Desenfileira implementação das operações Enfileira e
(função mod do Pascal). Desenfileira quando a fila está vazia.
procedure Enfileira ( x : TipoItem ; var Fila : TipoFila ) ; • Quando a fila está vazia, os apontadores
begin
Frente e Trás apontam para a célula cabeça.
i f Fila .Tras mod MaxTam + 1 = Fila . Frente
then writeln ( ’ Erro : f i l a esta cheia ’ ) • Para enfileirar um novo item, basta criar uma
else begin célula nova, ligá-la após a célula que contém
Fila . Item [ Fila .Tras ] : = x ; xn e colocar nela o novo item.
Fila .Tras : = Fila .Tras mod MaxTam + 1;
end; • Para desenfileirar o item x1 , basta desligar a
end; célula cabeça da lista e a célula que contém
x1 passa a ser a célula cabeça.
procedure Desenfileira ( var Fila : TipoFila ;
- x1 - ··· - xn - nil
var Item : TipoItem ) ;
begin 6 6
i f Vazia ( Fila )
Frente Trás
then writeln ( ’ Erro : f i l a esta vazia ’ )
else begin
Item : = Fila . Item [ Fila . Frente ] ;
Fila . Frente : = Fila . Frente mod MaxTam + 1;
end;
end;
Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.3.2 48 Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.3.2 49

Estrutura da Fila Usando Apontadores Operações sobre Filas Usando


Apontadores
• A fila é implementada por meio de células.
procedure FFVazia ( var Fila : TipoFila ) ;
• Cada célula contém um item da fila e um
begin
apontador para outra célula.
new ( Fila . Frente ) ;
• O registro TipoFila contém um apontador Fila .Tras : = Fila . Frente ;

para a frente da fila (célula cabeça) e um Fila . Frente^.Prox : = n i l ;


end;
apontador para a parte de trás da fila.

type function Vazia ( var Fila : TipoFila ) : boolean;


Apontador = ^Celula ; begin
TipoItem = record Vazia : = Fila . Frente = Fila .Tras;
Chave: TipoChave; end;
{ outros componentes }
end; procedure Enfileira ( x : TipoItem ; var Fila : TipoFila ) ;
Celula = record begin
Item : TipoItem ; new ( Fila .Tras^.Prox ) ;
Prox : Apontador; Fila .Tras : = Fila .Tras^.Prox;
end; Fila .Tras^.Item : = x ;
TipoFila = record Fila .Tras^.Prox : = n i l ;
Frente : Apontador; end;
Tras : Apontador;
end;

Projeto de Algoritmos – Cap.3 Estruturas de Dados Básicas – Seção 3.3.2 50

Operações sobre Filas Usando


Apontadores

procedure Desenfileira ( var Fila : TipoFila ;


var Item : TipoItem ) ;
var q : Apontador;
begin
i f Vazia ( Fila )
then writeln ( ’ Erro : f i l a esta vazia ’ )
else begin
q : = Fila . Frente ;
Fila . Frente : = Fila . Frente^.Prox;
Item : = Fila . Frente^.Item ;
dispose (q) ;
end;
end;

Você também pode gostar