You are on page 1of 18

ESTRUTURA

DE DADOS

Mauricio Saraiva
Listas encadeadas duplas
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:

 Identificar o uso de uma lista encadeada dupla.


 Reconhecer a navegação em uma lista encadeada dupla para inserir,
remover, atualizar e consultar valores.
 Aplicar a implementação de listas encadeadas duplas.

Introdução
Uma lista encadeada dupla é um tipo de lista dinâmica em que os ele-
mentos têm dois apontamentos: um para o elemento anterior e outro para
o elemento posterior. Com o encadeamento duplo, é possível percorrer
uma lista em ambos os sentidos, isto é, da esquerda para a direita e vice-
-versa, proporcionando mais versatilidade na navegação dos elementos
da lista. As operações em uma lista com encadeamento duplo são as
mesmas das listas simplesmente encadeadas, com pequenas variações
nos apontamentos existentes.
Neste capítulo, você vai estudar sobre o uso, a navegação e as ope-
rações com listas encadeadas duplas.

Lista encadeada dupla


Assim como uma lista encadeada simples, uma lista encadeada dupla é uma
relação de elementos ligados como uma sequência de itens. No entanto, no
encadeamento duplo, os elementos têm dois apontamentos, isto é, um para o
elemento anterior e outro para o posterior (EDELWEISS; GALANTE, 2009).
O primeiro e o último elementos da lista têm apenas um apontamento para
outros elementos, sendo que o anterior do primeiro e o posterior ao último
apontam para NULL, indicando o início e o final da lista, respectivamente,
como ilustrado a Figura 1.
2 Listas encadeadas duplas

a e1 p a e3 p a e3 p

Figura 1. Apresentação de uma lista encadeada dupla.

De acordo com Celes, Cerqueira e Rangel (2004), uma lista dinâmica com
encadeamento duplo apresenta as seguintes características:

 Define um ponteiro para o primeiro elemento e outro para o último


elemento da lista. Esses ponteiros servem como ponto de referência
da lista e permitirão que ela seja percorrida, tanto a partir do início,
quanto do final.
 Cada elemento da lista tem dois atributos, do tipo ponteiro da lista, que
apontam para os elementos anterior e posterior.
 O anterior ao primeiro elemento aponta para null, indicando que a lista
inicia a partir desse elemento.
 O posterior ao último elemento da lista aponta para null, indicando que
a lista termina nesse elemento.
 Os elementos da lista podem ser variáveis de um tipo de dado primitivo
ou estruturas compostas por outras variáveis, como registros.

Na linguagem C, a declaração de uma lista duplamente encadeada pode


ser implementada com duas estruturas. A primeira especifica os detalhes do
que será armazenado como um registro, isto é, os atributos que compõem esse
conjunto de dados; e a segunda define propriamente a lista, ou seja, os dados
que serão armazenados e os ponteiros que indicam os elementos anterior e
posterior (LORENZI; MATTOS; CARVALHO, 2007).
Pode-se, ainda, declarar uma terceira estrutura para armazenar a quantidade
de elementos da lista, bem como o endereço de memória do primeiro e do
último elemento da lista. Essa estrutura é chamada de Descritor por Edelweiss
e Galante (2009) e serve de apoio para manipular a lista nos dois sentidos,
como, por exemplo, imprimir os elementos de trás para frente.
Listas encadeadas duplas 3

Para exemplificar a declaração de uma lista dinâmica com encadeamento


duplo, tomamos por base o cadastro de alunos de uma escola. Esse cadastro
é composto por três atributos: nome, nota e turma.

A estrutura declarada nada mais é que a definição de um conjunto capaz


de armazenar os dados dos alunos. Entretanto, para declarar a lista, é preciso
definir uma estrutura que armazene um dado de Aluno e dois ponteiros, os
quais serão utilizados para fazer a ligação dos elementos:

Nessa estrutura, a variável dado é do tipo Aluno, isto é, armazena os atri-


butos dos alunos, como nome, nota e turma. Além disso, define as variáveis
*ant e *prox, como ponteiros para a mesma estrutura, que visam a armazenar
o endereço do anterior e do próximo elemento da lista.
A estrutura Descritor contém três variáveis, sendo uma do tipo inteiro
que armazena a quantidade de elementos da lista e duas do tipo ponteiro de
Nodo, que armazenam os endereços de memória do primeiro e do último
elemento da lista.
4 Listas encadeadas duplas

Por ser uma lista dinâmica, a alocação e a liberação de memória ocorrem


em tempo de execução. Assim, a lista ocupa apenas o espaço necessário para
acomodar os elementos atuais, tornando-se uma ótima opção para os casos
em que não se sabe exatamente o tamanho da lista.
Uma vez que as estruturas estejam definidas, é preciso declarar as variáveis
que serão usadas para montar a lista. Para isso, declaramos uma variável do
tipo Aluno, uma variável do tipo Descritor e uma variável que representa a
lista, do tipo Nodo.

É preciso alocar memória para cada elemento a ser incluído na lista.


Na linguagem C, a instrução malloc realiza essa alocação com base no tamanho
da estrutura Nodo que, além de armazenar os dados do Aluno, armazena os
endereços dos nodos anterior e posterior.

Navegação em uma lista encadeada dupla para


inserir, remover, atualizar e consultar valores

Navegar em uma lista


A navegação em uma lista encadeada dupla pode ser realizada de duas for-
mas. A primeira e mais usual é a varredura a partir de seu início, por meio
do endereço do primeiro elemento. Já a segunda maneira varre a lista de trás
para frente, partindo do endereço do último elemento, cujo endereço está
armazenado no Descritor (EDELWEISS; GALANTE, 2009).
Ambas as formas precisam de uma estrutura de repetição, a qual fará a
navegação na lista pelos ponteiros que endereçam para os elementos anterior
e posterior de cada item da lista, fazendo com que seja possível percorrê-la
em qualquer sentido, conforme ilustra a Figura 2.
Listas encadeadas duplas 5

Aluno
nome
nota
turma

&ant &ant &ant &ant

e1 e2 e3 e4
&prox &prox &prox &prox

&e1 n = 4 &e4
Descritor

Figura 2. Navegação em uma lista duplamente encadeada.

Incluir elemento na lista


A inclusão de elementos em uma lista duplamente encadeada pode ser rea-
lizada de três formas: no início, em uma posição intermediária e no final da
lista. Em cada uma dessas opções é preciso reajustar os apontamentos, de
modo que os elementos se liguem aos anteriores e posteriores (EDELWEISS;
GALANTE, 2009).
Para incluir um elemento na lista, é necessário alocar memória para receber
os dados do registro que serão armazenados na estrutura. Na sequência, deve-
-se redirecionar o ponteiro ant do novo elemento para o elemento anterior e
o ponteiro prox para o próximo elemento, cuidando para que o anterior do
primeiro elemento e o posterior do último apontem para NULL, indicando o
início e o final da lista, respectivamente (Figura 3).
6 Listas encadeadas duplas

a e1 p a e3 p a e3 p

a e4 p

a e1 p a e3 p a e3 p

Figura 3. Inclusão em uma lista duplamente encadeada.

Excluir elemento da lista


Assim como na inclusão, a exclusão de elementos de uma lista encadeada dupla
pode ser realizada de três formas: no início, em uma posição intermediária e
no final da lista. Em cada uma dessas opções, é necessário reajustar os apon-
tamentos, de modo que os elementos se liguem aos anteriores e posteriores
(CELES; CERQUEIRA; RANGEL, 2004).
Para excluir um elemento na lista, é preciso liberar a memória que estava
alocada para guardar os dados do registro, bem como cuidar para que o anterior
do primeiro elemento e o posterior do último apontem para NULL quando a
exclusão envolver o início ou o final da lista (Figura 4).
Listas encadeadas duplas 7

a e4 p

a e1 p a e3 p a p

a e4 p

a e1 p a e3 p

Figura 4. Exclusão em uma lista duplamente encadeada.

Consultar e atualizar elementos da lista


A consulta e a atualização de elementos em uma lista duplamente encadeada
são realizadas a partir da navegação nos itens da lista. Isso é necessário porque
a lista não tem um índice que acesse diretamente seus elementos, exceto o
primeiro e o último (LORENZI; MATTOS; CARVALHO, 2007).
Como citado anteriormente, a navegação pode ser realizada por meio de
uma estrutura de repetição. Dessa forma, as comparações podem ser realizadas,
ao percorrer a lista, visando a encontrar um determinado elemento que pode
ser apenas apresentado na tela ou até mesmo modificado.
Essas operações não requerem modificação nos ponteiros que ligam os
elementos, uma vez que apenas efetuam leitura ou atualização do conteúdo
dos itens, isto é, dos dados. Com isso, permanece a mesma quantidade de
elementos e seus respectivos apontamentos.
8 Listas encadeadas duplas

Implementação de listas encadeadas duplas


Nesta seção, vamos apresentar a implementação de uma lista duplamente
encadeada na linguagem C, tomando por base as estruturas apresentadas
anteriormente. Assim, serão demonstradas as principais operações, como
iniciar uma lista, verificar se uma lista está vazia, retornar o primeiro e o último
elementos, incluir e excluir elementos no início e no final de uma lista, excluir
uma lista inteira e imprimir a relação completa de elementos de uma lista.

Iniciar uma lista


É preciso iniciar uma lista antes de utilizá-la pela primeira vez. Nessa função,
inicializam-se as variáveis Ponteiros e a quantidade de elementos do Descritor.

Verificar se a lista está vazia


Uma lista dinâmica está vazia se ela aponta para NULL ou se a quantidade de
elementos do Descritor for igual a zero. Isso significa que nenhum elemento
foi inserido ou que todos já foram excluídos. A função que identifica se uma
lista está vazia está descrita a seguir.
Listas encadeadas duplas 9

Acessar o primeiro e o último elementos da lista


Para acessar o primeiro ou o último elemento da lista, devem-se usar os
ponteiros do Descritor, os quais têm apontamentos para esses elementos,
conforme apresentado a seguir.

Incluir elemento na lista


Nesta seção, vamos apresentar a inclusão no início e no final da lista. Para
isso, verificamos se a lista está vazia para identificar a forma correta de incluir,
pois a regra é diferente quando já existem elementos na lista. Além disso,
devem-se ajustar os apontamentos dos ponteiros do novo elemento na lista,
conforme apresentado anteriormente.
10 Listas encadeadas duplas

Excluir elemento da lista


Assim como na inclusão, vamos apresentar as funções que excluem no início
e no final da lista. Para isso, deve-se diminuir a quantidade de elementos do
Descritor, bem como liberar a memória do elemento excluído sem deixar de
ajustar os apontamentos.
Listas encadeadas duplas 11

Excluir toda a lista


Para excluir toda a lista, é preciso realizar a navegação desde o início e liberar
a memória de cada elemento, diminuindo o contador do Descritor.
12 Listas encadeadas duplas

Imprimir toda a lista


Há duas formas de imprimir toda a relação de elementos de uma lista dinâmica
com duplo encadeamento. A primeira é percorrê-la da esquerda para a direita
ou do início até o final, e a segunda é da direita para a esquerda ou do final
até o início.
A função imprimir pode ser personalizada para filtrar dados e apresentar
apenas determinados registros. Para isso, uma estrutura condicional precisa
ser implementada para verificar se os registros pesquisados atendem aos cri-
térios especificados. A condição de parada do laço de repetição se dá quando
o ponteiro do final ou do início da lista aponta para NULL.
Listas encadeadas duplas 13

CELES, W.; CERQUEIRA, R.; RANGEL, J. L. Introdução a estrutura de dados: com técnicas
de programação em C. Rio de Janeiro: Campus, 2004. 294 p.
EDELWEISS, N.; GALANTE, R. Estrutura de dados. Porto Alegre: Bookman, 2009. 262 p.
(Série Livros Didáticos Informática UFRGS, 18).
LORENZI, F.; MATTOS, P.; CARVALHO, T. Estruturas de dados. São Paulo: Cengage Le-
arning, 2007. 200 p.

Leitura recomendada
FORBELLONE, A. L. V.; EBERSPÁCHER, H. F. Lógica de programação: a construção de
algoritmos e estruturas de dados. 3 ed. São Paulo, Pearson, 2005. 232 p.
Encerra aqui o trecho do livro disponibilizado para
esta Unidade de Aprendizagem. Na Biblioteca Virtual
da Instituição, você encontra a obra na íntegra.
Conteúdo:

You might also like