You are on page 1of 18

ESTRUTURA

DE DADOS

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

„„ Reconhecer uma lista encadeada simples.


„„ Especificar operações de manipulação de uma lista encadeada simples.
„„ Identificar operações de acesso a uma lista encadeada simples.

Introdução
As listas encadeadas simples são normalmente utilizadas para relacionar
itens que precisam ser exibidos ou manipulados por meio de estruturas
dinâmicas. Com isso, é possível implementar operações que permitem
redimensionar as listas de acordo com a quantidade de itens manipulados,
ocupando exatamente a memória necessária para alocar os elementos
que pertencem à lista. Conhecer a definição das listas encadeadas sim-
ples, bem como suas operações de manipulação e acesso, permite que
o profissional de TI (tecnologia da informação) identifique e aplique
soluções confiáveis e otimizadas para o desenvolvimento de sistemas.
Neste capítulo, você vai estudar sobre listas encadeadas simples e
suas operações de manipulação e acesso.

Lista encadeada simples


Uma lista encadeada simples, ou lista dinâmica simplesmente encadeada,
é uma relação de elementos ligados em sequência, em que cada elemento é
composto de uma estrutura que pode conter variáveis de diversos tipos de
dados. Nesse tipo de lista, os elementos são alocados e deslocados em tempo
de execução, fazendo com que a lista cresça ou diminua dinamicamente de
acordo com a necessidade da aplicação (EDELWEISS; GALANTE, 2009).
2 Listas encadeadas simples

A ligação entre os elementos da lista ocorre pelo encadeamento simples, isto


é, cada nó que armazena um elemento da estrutura guarda o endereço físico
do próximo elemento na memória, isso faz com que não seja preciso alocar
espaços contínuos de memória, como as listas estáticas, pois o encadeamento
é lógico e não físico (Figura 1) (CELES; CERQUEIRA; RANGEL, 2004).

Mapa da memória principal

a b

c d

e f

Lista: a -> b -> c -> d -> e -> f

Figura 1. Representação na memória de uma lista encadeada simples.

A forma que um elemento tem de acessar o endereço físico da memória do


próximo elemento da lista se dá por meio de ponteiros. Os ponteiros funcionam
como apontadores que fazem referência a determinadas posições de memória,
isto é, toda variável declarada, seja de um tipo primitivo ou composto, tem
um endereço referenciado na memória e esse endereço é usado para realizar
o encadeamento da lista.
A estrutura de um elemento em uma lista encadeada simples é dividida em
três partes (Figura 2) (MATTOS; LORENZI; CARVALHO, 2007).
Listas encadeadas simples 3

&e1

e1

&prox
Figura 2. Estrutura de um elemento de uma lista encadeada.

„„ &e1 representa o endereço do próprio elemento na memória;


„„ e1 armazena o conteúdo do elemento, que pode ser apenas um tipo
primitivo ou um tipo composto que contém inúmeras variáveis de
diferentes tipos de dados;
„„ &prox indica o endereço físico da memória do próximo elemento da lista.

O encadeamento simples define que os elementos armazenam o endereço


da memória do próximo elemento da lista. Isso significa que a lista só pode
ser percorrida em um único sentido, a partir do início até a última posição, a
qual aponta para nulo, ou seja, para nenhum outro elemento (EDELWEISS;
GALANTE, 2009).
A estrutura de uma lista simplesmente encadeada está ilustrada pela
Figura 3. Nesse exemplo, percebe-se que cada elemento aponta para o en-
dereço do próximo elemento da lista, até que o último dos elementos aponte
para nulo, finalizando assim a relação.

&e1 &e2 &e3 &e4

e1 e2 e3 e4

&prox &prox &prox &prox

Figura 3. Ilustração de uma lista encadeada.


4 Listas encadeadas simples

Diferente de filas e pilhas, que têm restrição no modo de incluir e excluir


itens, as listas encadeadas simples são mais abrangentes e permitem adicionar
e remover elementos em qualquer posição e em qualquer ordem da relação
(CELES; CERQUEIRA; RANGEL, 2004).
Uma lista encadeada, por ser dinâmica, realiza a alocação da memória
para armazenar um novo elemento apenas quando este for incluído e, em
contrapartida, libera a memória quando determinado elemento é excluído,
ocupando apenas o espaço suficiente na memória para o tamanho atual da
lista (EDELWEISS; GALANTE, 2009).
O limite de elementos de uma lista encadeada simples é determinado pela
quantidade de memória que estiver disponível no dispositivo ou na máquina
virtual que rodar o aplicativo. Para isso, algumas linguagens de programação
oferecem comandos específicos para alocar e liberar recursos de memória em
tempo de execução (MATTOS; LORENZI; CARVALHO, 2007).
Não existe um índice de acesso direto aos elementos de uma lista dinâmica.
A lista mantém o endereço da posição inicial, sendo necessário percorrer os
itens de forma sequencial para encontrar determinado elemento na relação.
Vantagens de uma lista dinâmica (FORBELLONE, 2005):

„„ crescimento e redução dinâmica: capacidade de crescer e reduzir a


lista em tempo de execução, sendo recomendada para listas grandes
que podem ter várias operações de inclusão e exclusão de elementos
em diversas posições;
„„ baixo custo de inserção e exclusão: ajusta o apontamento de memória
em apenas dois elementos a cada modificação realizada (anterior e
posterior);
„„ alocação dinâmica de memória: proporciona otimização da memória
principal, usando apenas o espaço necessário para acomodar os ele-
mentos da lista;
„„ alocação eficiente: a alocação de endereços de memória é gerenciada
pelo sistema operacional pelas funções da linguagem de programação.

Desvantagens de uma lista dinâmica (FORBELLONE, 2005):

„„ alto custo de pesquisa: não existe um índice de acesso direto, devendo


realizar busca sequencial;
„„ tempo crescente de busca: o tempo gasto para encontrar elementos
cresce de acordo com o tamanho da lista.
Listas encadeadas simples 5

“Não liberar memória alocada dinamicamente quando ela não mais for necessária
pode fazer com que o sistema esgote prematuramente sua memória. Algumas vezes
isso é chamado um vazamento de memória” (DEITEL; DEITEL, 2010, p. 552).

Operações de manipulação de uma lista


encadeada simples
As operações de manipulação de uma lista encadeada simples permitem efe-
tuar as ações que modificam a lista, como incluir, excluir e alterar elementos.
Dessas operações, a inclusão e a exclusão podem ser realizadas em qualquer
posição da lista, com tratamentos diferenciados para cada caso.

Definir uma lista


Uma lista encadeada simples é uma relação de elementos ligados em sequência.
Esses elementos normalmente são formados por estruturas compostas por
diversas variáveis, como um registro, as quais compreendem um domínio de
aplicação. São exemplos de estruturas (EDELWEISS; GALANTE, 2009):

„„ dados de cadastro de clientes: CPF, nome, data de nascimento, ende-


reço, etc.;
„„ características de um produto: código de barras, descrição, categoria,
preço, etc.;
„„ estoque de produtos: código de barras, quantidade em estoque, preço
de aquisição, data de aquisição, etc.;
„„ itens de venda de uma nota fiscal: número da nota, data de emissão,
CPF ou CNPJ do cliente, relação de produtos vendidos, etc.

A definição da lista estabelece a declaração de sua estrutura, incluindo as


variáveis e os seus tipos de dados, bem como uma variável adicional como
um ponteiro do mesmo tipo da lista para realizar o encadeamento entre os
elementos:
6 Listas encadeadas simples

//Definição da estrutura Produto


estrutura Produto (
codigoBarras : texto
descricao : texto
categoria : número inteiro
preco : número real)
//Definição da estrutura da listaProduto
estrutura ListaProduto (
produto : Produto
estrutura [ponteiro] proximoElemento : ListaProduto)

Inicializar uma lista


É preciso inicializar a lista antes de inserir algum elemento. Essa atividade é
bastante simples e requer, apenas, que seja definida como nula a variável que
identifica o próximo elemento da lista:

listaProduto.proximo = nulo

Incluir elemento na lista


Antes inserir um novo elemento na lista é preciso alocar um espaço de memória
para ele e, em seguida, preenchê-lo com os dados do registro. A inclusão de
um elemento pode ser realizada em qualquer posição da lista, sem precisar
deslocar os demais elementos. Isso ocorre porque, em uma lista dinâmica,
são modificados apenas os apontamentos entre os elementos, mantendo-os
nas posições de memória em que foram alocados.
A inclusão em uma lista encadeada simples pode ser realizada de três
maneiras distintas: no início, no final ou em qualquer posição intermediária
da lista. Para isso, devem ser ajustados os apontamentos que indicam quem
são os próximos elementos, para que a lista permaneça ligada e linear:

//Alocação de memória e atribuição de valores ao novo registro


novoProduto = alocarMemoria(listaProduto)
listaProduto.novoProduto.codigoBarras= 98712545611701
listaProduto.novoProduto.descricao= “Bolo de cenoura”
listaProduto.novoProduto.categoria= 1
listaProduto.novoProduto.preço= 5,99
Listas encadeadas simples 7

Incluir no início da lista

Incluir um novo elemento no início da lista é uma tarefa simples. Para isso, é
preciso ajustar o apontamento inicial da lista, que vai indicá-lo como primeiro
elemento, definindo como seu próximo elemento aquele que ocupava essa
posição anteriormente (Figura 4).

d
c
a e
b

d
a c
b e

Figura 4. Inclusão de um elemento no início da lista.

novoProduto.proximo = listaProduto.proximo
listaProduto.proximo = novoProduto
8 Listas encadeadas simples

Incluir no final da lista

Incluir um elemento no final da lista também é uma tarefa simples. Basta


percorrer a lista até a última posição, fazer com que o último elemento aponte
para o novo e este para nulo, pois o último elemento deve, necessariamente,
apontar para nulo para indicar o final da lista (Figura 5).

d
c
a b e

x
d
a c
b e

Figura 5. Inclusão de um elemento no final da lista.

enquanto listaProduto.proximo diferente nulo


ultimo= listaProduto.proximo
fim enquanto
ultimo.proximo= novoProduto

Incluir no meio da lista

Para incluir um elemento em uma posição intermediária da lista, é preciso fazer


uma varredura até a posição desejada e alterar os apontamentos, fazendo com
que o elemento anterior aponte para o novo e este para o elemento próximo
elemento (Figura 6).
Listas encadeadas simples 9

d
a c
b e

d
a c
b e

Figura 6. Inclusão de um elemento no meio da lista.

enquanto listaProduto.proximo diferente nulo


se posição igual a posição desejada
temp= listaProduto.proximo
listaProduto.proximo= novoProduto
novoProduto.proximo= temp
fim se
fim enquanto

Excluir elemento da lista


Assim como a inclusão, a exclusão pode ser realizada em qualquer elemento
da lista. Para isso, é preciso encerrar as ligações anteriores e posteriores do
elemento que foi excluído, religando seu antecessor ao seu sucessor, mantendo
a lista ligada e linear.
Além disso, deve ocorrer a liberação da memória que estava alocada para o
item que foi excluído, fazendo com que a lista armazene apenas a quantidade
de memória necessária para o seu tamanho atual. Como exemplo, a Figura 7
apresenta a exclusão de um elemento posicionado no meio da lista.
10 Listas encadeadas simples

d
a c
b e

d
a
b e

Figura 7. Exclusão de item da lista dinâmica.

Excluir no início da lista

Excluir um elemento do início da lista é uma atividade muito simples. Para


isso, basta fazer com que a lista inicie pelo elemento que era sucessor do
elemento que foi excluído, bem como liberar a memória desse elemento que
deixou de pertencer à lista.

primeiro= listaProduto.proximo
listaProduto.proximo= primeiro.proximo
liberarMemoria(primeiro)

Excluir no final da lista

Para excluir um elemento do final, é preciso fazer uma varredura na lista até
chegar à última posição, definir o apontamento do penúltimo elemento como
nulo e liberar a memória do elemento que ocupava a última posição.

anterior= listaProduto
atual= listaProduto.proximo
enquanto atual.proximo diferente nulo
anterior= atual
atual= atual.proximo
Listas encadeadas simples 11

fim enquanto
anterior.proximo= nulo
liberarMemoria(atual)

Excluir no meio da lista

Para excluir um elemento que ocupa uma posição intermediária, é necessário


percorrer a lista até encontrar o elemento desejado, identificando seu anterior
e sucessor. Na sequência, basta fazer o anterior apontar para o sucessor, bem
como liberar a memória que estava alocada para o elemento excluído.

anterior= listaProduto
atual= lisProduto.proximo
enquanto atual.proximo diferente nulo
se atual.proximo igual a valor
anterior.proximo= atual.proximo
liberarMemoria(atual)
sair
fim se
anterior= atual
atual= atual.proximo
fim enquanto

Excluir toda a lista

Para excluir uma lista encadeada inteira, é preciso percorrer todos os elementos,
a partir do início, e liberar a alocação de memória de cada elemento, bem como
indicar que seu próximo elemento aponta para nulo para evitar o apontamento
de alguma posição desatualizada na memória.

atual= listaProduto
enquanto atual.proximo diferente nulo
proximo= atual.proximo
atual.proximo= nulo
liberarMemoria(atual)
fim enquanto
12 Listas encadeadas simples

Operações de acesso a uma lista encadeada


simples
As operações de acesso a uma lista encadeada simples realizam as ações de
leitura, pesquisa e impressão, sem efetuar qualquer modificação. São consi-
deradas ações de apoio à manipulação de dados, pois atuam sobre os dados
já inseridos na lista.
Podem ser criadas diversas operações de acesso a uma lista, sendo que as
principais são: verificar se a lista está vazia, identificar o primeiro e o último
elementos, pesquisar um elemento qualquer por determinada informação e
imprimir a relação completa de elementos da lista.

Verificar se a lista está vazia

Uma lista encadeada está vazia se ela aponta para nulo, isto é, se ela não
aponta para nenhum elemento.

se (listaProduto.proximo igual a nulo) então


retornar positivo
senão
retornar negativo
fim se

Acessar o primeiro elemento da lista

Para acessar o primeiro elemento da lista, basta pegar o próximo elemento


do endereço da lista, já que esse endereço aponta para o primeiro elemento.

primeiro= listaProduto.proximo
imprime primeiro

Acessar o último elemento da lista

Não é possível acessar diretamente o último elemento da lista, uma vez que
uma lista encadeada simples não permite acesso direto aos elementos. Dessa
forma, é preciso percorrer toda a lista a partir do primeiro elemento.
Listas encadeadas simples 13

elemento= listaProduto.proximo
enquanto elemento diferente nulo
se elemento.proximo igual a nulo
imprime elemento
fim se
elemento= listaProduto.proximo
fim enquanto

Pesquisar elemento na lista

Sabendo que uma lista encadeada simples não permite acessar diretamente
os elementos, é preciso realizar uma varredura na lista a partir da primeira
posição. Dessa forma, compara-se cada elemento da lista com o dado pesqui-
sado, buscando localizar a informação desejada.

elemento= listaProduto.proximo
enquanto elemento diferente nulo
se elemento.proximo igual a informação desejada
imprime elemento
fim se
elemento= listaProduto.proximo
fim enquanto

Imprimir toda a lista

Para imprimir a relação completa de elementos de uma lista encadeada sim-


ples, é preciso percorrer a lista a partir da primeira posição até que o último
elemento aponte para nulo.

elemento= listaProduto.proximo
enquanto elemento diferente nulo
imprime elemento
elemento= listaProduto.proximo
fim enquanto
14 Listas encadeadas simples

CELES, W.; CERQUEIRA, R.; RANGEL, J. L. Introdução a estrutura de dados. São Paulo:
Campus, 2004.
DEITEL, P. J.; DEITEL, H. M. Como programar em C. 6. ed. São Paulo: Pearson, 2011.
EDELWEISS, N.; GALANTE, R. Estrutura de dados. Porto Alegre: Bookman, 2009. (Série
Livros Didáticos Informática UFRGS, v. 18).
FORBELLONE, A. L. Lógica de programação: a construção de algoritmos e estruturas
de dados. 3. ed. São Paulo: Prentice Hall, 2005.
MATTOS, P.; LORENZI, F.; CARVALHO, T. Estruturas de dados. São Paulo: Thomson, 2007.
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