You are on page 1of 9

Listas Lineares

ED 06 Listas Encadeadas
Prof. Dr. Marcelo Duduchi

Conforme j vimos, uma lista uma coleo de elementos do mesmo tipo dispostos linearmente que podem ou no seguir uma determinada organizao. Exemplo: [E1, E2, E3, E4, E5, ..., En], onde n deve ser > = 0; At aqui usamos alocao seqencial para implement-las mas a partir de agora usaremos a alocao encadeada.

Listas Encadeadas
Listas encadeadas so listas lineares em que os elementos no necessariamente encontram-se dispostos numa rea continua de memria; Como no se encontram numa rea continua de memria necessrio ter alguma forma de relacion-los entre s; A forma utilizada para relacion-los incluir em cada elemento, alm do valor armazenado uma referncia de onde est o prximo elemento da lista;
data

Listas Encadeadas Simples


Cada elemento (nodo) da lista ser formado pelo dado (data) a armazenar e uma referncia (link) para o prximo:
Nodo:

link

Listas Encadeadas Simples


Uma lista encadeada ser formada ento por diversos nodos inter relacionados por links e acessada a partir de uma referncia inicial:
Referncia inicial

Listas Encadeadas Simples


Em Java necessrio, antes de tudo, criarmos a classe Nodo composta por uma ou mais reas de dados (data) que no exemplo do tipo char e uma rea que referencie o prximo (link): type ptr=^nodo; Nodo: nodo= record data:char; link:ptr; end; data link

Lista encadeada

auto referncia

Listas Encadeadas Simples


Para criar uma lista como a abaixo poderamos usar o seguinte conjunto de instrues em Pascal: new(lista); lista^.data = C; lista^.link = new Nodo(); lista^.link.^data = A; new(aux); aux^.data = D; aux^.link = new Nodo(); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;

Listas Encadeadas Simples


Vejamos a execuo passo a passo:
new(lista); lista^.data = C; lista^.link = new Nodo(); lista^.link.^data = A; new(aux); aux^.data = D; aux^.link = new Nodo(); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;

lista

Listas Encadeadas Simples


Estamos considerando a existncia de um ponteiro lista e outro aux...
Referncia auxiliar lista aux lista aux

Listas Encadeadas Simples


Criando o primeiro nodo e atribuindo sua referncia lista...
Referncia auxiliar

new(lista); lista^.data = C; new(lista^.link); lista^.link.^data = A; new(aux); aux^.data = D; new(aux^.link); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;

new(lista); lista^.data = C; new(lista^.link); lista^.link.^data = A; new(aux); aux^.data = D; new(aux^.link); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;

Listas Encadeadas Simples


Colocando o valor C na parte data da rea referenciada por lista...
Referncia auxiliar lista aux

Listas Encadeadas Simples


Criando o segundo nodo e atribuindo sua referncia lista.link...
Referncia auxiliar lista aux

new(lista); lista^.data = C; new(lista^.link); lista^.link.^data = A; new(aux); aux^.data = D; new(aux^.link); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;

new(lista); lista^.data = C; new(lista^.link); lista^.link.^data = A; new(aux); aux^.data = D; new(aux^.link); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;

Listas Encadeadas Simples


Colocando o valor A na parte data da rea referenciada por lista.link ...
Referncia auxiliar lista aux aux lista Referncia auxiliar

Listas Encadeadas Simples


Cria um novo nodo e coloca sua referncia na rea auxiliar criada...
new(lista); lista^.data = C; new(lista^.link); lista^.link.^data = A; new(aux); aux^.data = D; new(aux^.link); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;

new(lista); lista^.data = C; new(lista^.link); lista^.link.^data = A; new(aux); aux^.data = D; new(aux^.link); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;

Listas Encadeadas Simples


Colocando o valor D na parte data da rea referenciada por aux...
Referncia auxiliar lista aux

Listas Encadeadas Simples


Criando um novo nodo e colocando sua referncia na parte link da rea referenciada por aux...
Referncia auxiliar lista aux

new(lista); lista^.data = C; new(lista^.link); lista^.link.^data = A; new(aux); aux^.data = D; new(aux^.link); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;

new(lista); lista^.data = C; new(lista^.link); lista^.link.^data = A; new(aux); aux^.data = D; new(aux^.link); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;

Listas Encadeadas Simples


Colocando o valor E na parte data da rea referenciada por aux.link ...
Referncia auxiliar lista aux

Listas Encadeadas Simples


Colocando nulo (nil) na parte link da rea referenciada por aux^.link...
Referncia auxiliar lista aux

new(lista); lista^.data = C; new(lista^.link); lista^.link.^data = A; new(aux); aux^.data = D; new(aux^.link); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;

new(lista); lista^.data = C; new(lista^.link); lista^.link.^data = A; new(aux); aux^.data = D; new(aux^.link); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;

Listas Encadeadas Simples


Ligando as duas listas ao colocar o contedo de aux na parte link da rea referenciada por lista.link... new(aux2);
// cria referncia aux2 e o novo nodo

Listas Encadeadas Simples


Note que seria muito fcil fazer um cdigo que permite incluir o elemento G no incio da lista: aux2^.data = G;
// coloca G no data do novo nodo

Referncia auxiliar lista aux


G // faz lista referenciar o novo nodo

new(lista); lista^.data = C; new(lista^.link); lista^.link.^data = A; new(aux); aux^.data = D; new(aux^.link); aux^.link^.data = E; aux^.link^.link = nil; lista^.link^.link = aux;
Referncia auxiliar aux2
// coloca referncia da lista no link // do novo nodo

aux2^.link = lista; lista = aux2;

lista

Listas Encadeadas Simples


Note que seria muito fcil fazer um cdigo que permite incluir o elemento G no incio da lista: new(aux2);
// cria na referncia aux2 o novo nodo

Listas Encadeadas Simples


O primeiro passo:
new(aux2);
// cria na referncia aux2 o novo nodo

aux2^.data = G;
// coloca G no data do novo nodo

aux2^.data = G;
// coloca G no data do novo nodo

aux2^.link = lista;
// coloca referncia da lista no link // do novo nodo

Referncia auxiliar lista

aux2

aux2^.link = lista;
// coloca referncia da lista no link // do novo nodo

lista
// faz lista referenciar o novo nodo G

lista = aux2;

lista = aux2;
// faz lista referenciar o novo nodo

Listas Encadeadas Simples


Mais um passo:
new(aux2);
// cria na referncia aux2 o novo nodo

Listas Encadeadas Simples


Vejamos a incluso de G passo a passo:
Referncia auxiliar aux2

new(aux2);
// cria na referncia aux2 o novo nodo

aux2^.data = G;
// coloca G no data do novo nodo

aux2^.data = G;
// coloca G no data do novo nodo

Referncia auxiliar aux2 lista


G

aux2^.link = lista;
// coloca referncia da lista no link // do novo nodo

aux2^.link = lista;
// coloca referncia da lista no link // do novo nodo

lista = aux2;
// faz lista referenciar o novo nodo

lista
G

lista = aux2;
// faz lista referenciar o novo nodo

Listas Encadeadas Simples


Vejamos a incluso de G passo a passo:
new(aux2);
// cria na referncia aux2 o novo nodo

Listas Encadeadas Simples


Note tambm que bastam 3 instruo em Pascal para retirar um elemento do incio da lista: aux = lista lista = lista^.link; dispose(aux); A funo dispose libera a rea de memria referenciada
lista aux

aux2^.data = G;
// coloca G no data do novo nodo

Referncia auxiliar aux2


// coloca referncia da lista no link // do novo nodo

aux2^.link = lista; lista = aux2;


// faz lista referenciar o novo nodo

lista
G C C A D E A D E

Listas Encadeadas Simples


aux3=lista; Para mostrar uma lista // referencia o inicio da lista em aux3 como a abaixo while(aux3<>nil) begin poderamos usar o // enquanto no chegar a nulo seguinte conjunto de writeln(aux3^.data); instrues em Java:

Listas Encadeadas Simples


aux3=lista;

Executando passo a passo...


Referncia auxiliar

// referencia o inicio da lista em aux3

while(aux3<>nil) begin
// enquanto no chegar a nulo

writeln(aux3^.data);
// mostra o data

// mostra o data

lista

Referncia auxiliar // vai para o prximo aux3

aux3=aux3^.link end;
lista

aux3=aux3^.link
// vai para o prximo aux3

end;

Listas Encadeadas Simples


aux3=lista;

Listas Encadeadas Simples


aux3=lista;

aux3 diferente de // referencia o inicio da lista em aux3 while(aux3<>nil) begin nulo ento entrar // enquanto no chegar a nulo no loop... writeln(aux3^.data);
// mostra o data Referncia auxiliar aux3

Mostra o valor da parte data da rea que aux3 referencia: C


Referncia auxiliar

// referencia o inicio da lista em aux3

while(aux3<>nil) begin
// enquanto no chegar a nulo

writeln(aux3^.data);
// mostra o data

aux3=aux3^.link
// vai para o prximo

aux3=aux3^.link
// vai para o prximo

lista

end;

lista

aux3

end;

Listas Encadeadas Simples


aux3=lista; aux3=lista;

Listas Encadeadas Simples


Como aux3 no nulo continua no loop e agora mostra A
while(aux3<>nil) begin
// enquanto no chegar a nulo // referencia o inicio da lista em aux3

Mostra o valor da parte data da rea que aux3 referencia...


while(aux3<>nil) begin
// enquanto no chegar a nulo

// referencia o inicio da lista em aux3

writeln(aux3^.data); writeln(aux3^.data);
// mostra o data // mostra o data

lista

Referncia auxiliar // vai para o prximo aux3 // vai para o prximo aux3

aux3=aux3^.link end; end;


lista Referncia auxiliar

aux3=aux3^.link

Listas Encadeadas Simples


aux3=lista;

Listas Encadeadas Simples


aux3=lista;

Vai para o prximo // referencia o inicio da lista em aux3 while(aux3<>nil) begin referenciando a // enquanto no chegar a nulo rea onde est o writeln(aux3^.data); valor D...
// mostra o data Referncia auxiliar // vai para o prximo aux3

Como o link3 no // referencia o inicio da lista em aux3 while(aux3<>nil) begin nulo continua o // enquanto no chegar a nulo loop mostrando o writeln(aux3^.data); valor D...
// mostra o data Referncia auxiliar

aux3=aux3^.link end;
lista

aux3=aux3^.link
// vai para o prximo aux3

lista

end;

Listas Encadeadas Simples


aux3=lista;

Listas Encadeadas Simples


aux3=lista;

Vai para o prximo // referencia o inicio da lista em aux3 while(aux3<>nil) begin referenciando a // enquanto no chegar a nulo rea onde est o writeln(aux3^.data); valor E...
// mostra o data Referncia auxiliar aux3

Como o aux3 no // referencia o inicio da lista em aux3 nulo o loop no while(aux3<>nil) begin // enquanto no chegar a nulo encerrado e o valor writeln(aux3^.data); E mostrado...
// mostra o data Referncia auxiliar

aux3=aux3^.link
// vai para o prximo

aux3=aux3^.link
// vai para o prximo

lista

end;

lista

aux3

end;

Listas Encadeadas Simples


aux3=lista; Como a parte link do nodo referenciado por aux3 nulo aux3 recebe nulo e ento sai do loop. while(aux3<>nil) begin
// enquanto no chegar a nulo // referencia o inicio da lista em aux3

Pilhas (Listas Encadeadas)


A rotina push inclui um elemento no incio da lista;
Referncia auxiliar aux lista
G procedure push(var topo:ptr; elem:char); var aux:ptr; begin new(aux); aux^.data:=elem; aux^.link:=topo; topo:=aux; end;

writeln(aux3^.data);
// mostra o data

lista

Referncia auxiliar // vai para o prximo aux3

aux3=aux3^.link end;

Pilhas (Listas Encadeadas)


Incluindo no cdigo a verificao se h espao
Referncia auxiliar aux topo auxptr lista
G procedure push(var topo:ptr; elem:char); var aux:ptr; begin if maxavail < sizeof(nodo) then begin writeln(overflow!); halt; end; new(aux); aux^.data:=elem; aux^.link:=topo; topo:=aux; end;

Pilhas (Listas Encadeadas)


A rotina pop exclui o primeiro elemento da lista, assim o primeiro que entra o primeiro que sai
aux
C function pop(var topo:ptr):char; var auxptr:ptr; aux:char; begin if topo = nil then begin writeln(underflow!); halt; end else begin aux:=topo^.data; auxptr:=topo; topo:=topo^.link; dispose(auxptr); pop:=aux; C A end; end;

Exerccio 1
Implemente as outras rotinas da pilha usando alocao dinmica encadeada. Lembre-se que a rotina create s coloca nil no topo e a rotina destroy percorre a lista retirando os elementos. A top bem parecida com a pop s que no retira nenhum elemento.

Exerccio 2
Implemente uma fila usando alocao dinmica. Lembre-se que a fila ter dois ponteiros (front e rear). O front aponta para o primeiro da lista e o rear aponta para o ltimo. Cuidado com os detalhes de implementao. Ao incluir o 1 elemento deve-se fazer front e rear apontarem para ele e ao excluir o ltimo elemento deve-se apontar front e rear para nil

Tcnicas de Encadeamento
Conheceremos agora algumas tcnicas de encadeamento:
Lista circular; Lista duplamente encaminhada; Lista com nodos sentinelas;
Referncia inicial
C A D E

Listas Encadeadas Circulares


Uma lista encadeada circular idntica a uma lista encadeada simples a no ser pela referncia final da lista que no referencia nulo e sim o primeiro da lista conforme o exemplo abaixo:

Lista encadeada circular

Listas Duplamente Encadeadas


Listas duplamente encadeadas so listas lineares em que cada elemento possui alm da rea de dados dois links:
Um que referencia o antecessor; Um que referencia o prximo;

Listas Duplamente Encadeadas


Note que na lista duplamente encadeada:
o ltimo elemento tem o link a direita nulo; o primeiro elemento tem o link esquerda nulo;
Referncia inicial

link

data

link

Lista duplamente encadeada

Nodos sentinelas
Os nodos sentinelas so nodos que ficam no incio e final da lista para que todas as operaes sejam realizadas entre os elementos da lista evitando manipulaes nas extremidades.
No incio coloca-se um valor menor que todos (Low-value ou LV) No final um valor maior que todos (high-value ou HV): lista

Exerccios com listas


1. Para implementarmos uma pilha usando listas encadeadas necessrio guardarmos somente a referncia inicial da lista como o topo da pilha. Sendo assim para incluir um elemento na pilha basta criar um novo nodo inclu-lo na 1a. posio da lista. Para retirar um elemento da pilha basta retirar o 1o. elemento da lista mantendo o prximo elemento como topo. Implemente os mtodos push e pop considerando que a classe nodo com um campo data do tipo int e um link j foi criada. - void push(Nodo topo, int elem) - int pop(Nodo topo)

LV

HV

Exerccios com listas


2. Construa um mtodo que retire a duplicidade de elementos de uma lista ordenada cuja referncia passada como parmetro. 3. Construa um mtodo que transforme uma lista ligada convencional cuja referncia passada como parmetro em uma lista circular. 4. Construa um mtodo que concatene duas listas ligadas convencionais cujas referncias so passadas como parmetro. 5. Construa um mtodo que conte e retorne a quantidade de elementos de uma lista ligada cuja referncia passada como parmetro. 6. Altere o mtodo do exerccio 5 de forma que este agora conte e retorne a quantidade de elementos de uma lista circular. 7. Construa um mtodo recursivo que mostre os elementos de uma lista ligada convencional. 8. Construa um mtodo que mostre os elementos de uma lista ligada convencional do ltimo para o primeiro. 9. Construa um mtodo que mostre os elementos de duas listas ordenadas cujas referncias so passadas como parmetro, intercalados de acordo com a ordem.

Exerccios com listas

Exerccios com listas


10. Construa um mtodo que crie uma nova lista retornando sua referncia a partir da intercalao de duas listas ordenadas cujas referncias so passadas como parmetro. 11. Considere uma coleo de elementos dispostos em ordem num vetor e outra coleo de elementos armazenados em uma lista dinmica ordenada. Seria vivel implementarmos um algoritmo de busca binria para as duas colees? Justifique sua resposta.

Exerccios com listas


12. Considerando que os mtodos next, destroy e isempty j foram desenvolvidos codifique os mtodos isfull para verificar se a fila circular est cheia e o mtodo store para inserir um elemento na fila. 13. Considerando que os mtodos destroy e isempty j foram desenvolvidos codifique o mtodo store para incluir um elemento numa fila implementada com listas encadeadas onde a referncia ao primeiro elemento o front e a referncia do ltimo elemento da lista o rear. 14. Compare as implementaes desenvolvidas nas questes 12 e 13 quanto a espao de memria e velocidade dos algoritmos.