LISTAS DUPLAMENTE ENCADEADAS
Listas Encadeadas: Características
• Listas encadeadas são percorridas do início ao final.
• E se for necessário percorrer uma lista nas duas
direções indiferentemente?
– Ex.: Ponteiro para o “nó anterior" necessário para muitas
operações (busca, inserção, ...)
• Utilização de um ponteiro extra em cada nó, que
indica o ponteiro anterior ao nó
• O gasto de memória imposto por um novo campo de
ponteiro é justificado pela facilidade no processamento de toda lista
Implementação de Listas com
Ponteiros
• Os nós (itens) da lista são registros com dois ponteiros,
para guardar o endereço do seu sucessor e antecessor
Antecessor (esq)
x1
x1
x2
x3
...
Sucessor (dir)
xn
Implementação da Lista Duplamente
Encadeada
type
Ponteiro
TipoItem
= ^TipoNo;
= record
chave: TipoChave;
{outros componentes desejadas...}
end;
TipoNo
= record
Item: TipoItem;
Ant, Prox: Ponteiro;
end;
TipoListaDupla = record
Primeiro: Ponteiro;
Último : Ponteiro;
end;
var L: TipoListaDupla;
Implementação: Inicia_Lista e
Lista_Vazia
procedure Inicia_Lista (var LD: TipoListaDupla);
begin
New (LD.Primeiro);
LD.Último := LD.Primeiro;
LD.Primeiro^.Prox := nil;{LD.Último^.Prox := nil}
LD.Primeiro^.Ant := nil;{LD.Último^.Ant := nil}
end;
function Lista_Vazia (var LD: TipoListaDupla): boolean;
begin
Lista_Vazia := LD.Último = LD.Primeiro;
end;
Implementação: Imprime_Lista
procedure Imprime_Lista(var LD: TipoLista);
var Aux: Ponteiro;
begin
Aux:= LD.Primeiro^.Prox;
while (Aux <> nil) do
begin
writeln (‘Chave: ‘, Aux^.Item.Chave);
Aux := Aux^.Dir;
end;
end;
Implementação: Imprime_Lista
procedure Imprime_Lista(var LD: TipoLista);
var Aux: Ponteiro;
begin
Aux:= LD.Ultimo;
while (Aux <> LD.Primeiro) do
begin
writeln (‘Chave: ‘, Aux^.Item.Chave);
Aux := Aux^.Esq;
end;
end;
Inserção de um Nó
• Duas situações: Inserção à Direita de um
nó e Inserção à Esquerda de um Nó
• Caso 1: Inserção à Direita
– Procedimento recebe o nó à esquerda do qual se
deseja inserir (o item vai ser inserido à
direita desse nó passado como parâmetro)
– Cria-se um novo nó
– Ponteiro à direita do novo nó recebe o ponteiro
à direita do nó passado como parâmetro
– Ponteiro à esquerda do novo nó recebe o ponteiro
passado como parâmetro
– Ponteiro à direita do nó passado como parâmetro
recebe o novo nó
– Ponteiro à esquerda do nó à direita do novo nó
recebe o novo nó
Inserção do Nó X à direita de P em
Lista Duplamente Encadeada
P
Último
Primeiro
cabeça
X
Inserção à direita de p
procedure Insere_a_Direita (p:Ponteiro; x:TipoItem; var
LD:TipoListaDupla; var flag: boolean);
{O nó será inserido à direita do ponteiro p passado como
parâmetro}
var pNovo: Ponteiro;
begin
new(pNovo);
if pNovo = nil then flag := FALSE
else begin
pNovo^.Item.chave := x.chave;
pNovo^.Prox := p^.Prox;
pNovo^.Ant := p;
p^.Prox := pNovo;
{Caso em que p aponta para o último
if pNovo^.prox = nil then
elemento, então o novo elemento será
LD.Ultimo := pNovo
último da lista}
else
pNovo^.Prox^.Esq := pNovo;
flag := TRUE;
end
end;
o
Inserção de um Nó
• Caso 2: Inserção à Esquerda
– Procedimento recebe o nó à direita do qual se
deseja inserir (o item vai ser inserido à
esquerda desse nó passado como parâmetro)
– Cria-se um novo nó
– Ponteiro à esquerda do novo nó recebe o ponteiro
à esquerda do nó passado como parâmetro
– Ponteiro à direita do novo nó recebe o ponteiro
passado como parâmetro
– Ponteiro à esquerda do nó passado como parâmetro
recebe o novo nó
– Ponteiro à direita do nó à esquerda do novo nó
recebe o novo nó
Inserção do Nó X à esquerda de P em
Lista Duplamente Encadeada
P
Primeiro
Último
cabeça
X
Inserção à esquerda de p
procedure Insere_a_Esquerda (p:Ponteiro; x:TipoItem; var
LD:TipoLista; var flag: boolean);
{ A inserção é feita à esquerda do ponteiro p }
var pNovo: Ponteiro;
begin
new(pNovo);
if pNovo = nil or p = LD.Primeiro then flag := FALSE
else begin
pNovo^.Item := x;
pNovo^.Prox := p;
pNovo^.Ant := p^.Ant;
p^.Ant := pNovo;
pNovo^.Esq^.Dir := pNovo;
flag := TRUE;
end
end;
Remoção de um Nó
• Também duas situações: Remoção à Direita
de um nó e Remoção à Esquerda de um Nó
• Caso 1: Remoção à Direita
– Procedimento recebe o nó à esquerda do qual se
deseja remover(o item vai ser removido à direita
desse nó passado como parâmetro)
– Cria-se um auxiliar para apontar para o nó à
direita
– Ponteiro à direita do nó passado como parâmetro
aponta para a direita do nó auxiliar
– Ponteiro à esquerda do nó à esquerda do nó
auxiliar aponta para o nó à esquerda do nó
auxiliar
– Retorna o ítem que está no nó auxiliar
– Apaga-se o nó auxiliar
Remoção do Nó X à direita de P em
Lista Duplamente Encadeada
P
Primeiro
cabeça
X
Último
Remoção à direita de p
procedure Remove_a_Direita (p:Ponteiro; x:TipoItem; var
LD:TipoListaDupla; var flag: boolean);
{O nó será removido à direita do ponteiro p passado como parâmetro}
var aux: Ponteiro;
begin
if Vazia(LD) or LD^.prox=nil then flag := false
else begin
aux := p^.prox;
x := aux^.Item;
p^.prox := aux^.Prox;
{Caso em que aux aponta para o último
if aux^.prox = nil then
elemento, então o apontador para última
LD.Ultimo := p
posição será P}
else
aux^.Prox^.Ant := aux^.Ant;
Dispose (aux);
flag := TRUE;
end
end;
Remoção à Esquerda de um Nó
• Caso 2: Remoção à Esquerda
– Procedimento recebe o nó à direita do qual se
deseja remover(o item vai ser removido à
esquerda desse nó passado como parâmetro)
– Cria-se um auxiliar para apontar para o nó à
esquerda
– Ponteiro à esquerda do nó passado como parâmetro
aponta para a esquerda do nó auxiliar
– Ponteiro à direita do nó à direita do nó
auxiliar aponta para o nó à direita do nó
auxiliar
– Retorna o ítem que está no nó auxiliar
– Apaga-se o nó auxiliar
Remoção do Nó X à Esquerda de P em
Lista Duplamente Encadeada
X
Primeiro
cabeça
P
Último
Remoção à direita de p
procedure Remove_a_Esquerda (p:Ponteiro; x:TipoItem; var
LD:TipoListaDupla; var flag: boolean);
{O nó será removido à esquerda do ponteiro p passado como parâmetro}
var aux: Ponteiro;
begin
if Vazia(LD) or p=LD.Primeiro then flag := false
else begin
aux := p^.ant;
x := aux^.Item;
p^.ant := aux^.ant;
aux^.Ant^.Prox := aux^.Prox;
Dispose (aux);
flag := TRUE;
end
end;
Download

Listas Duplamente Encadeadas