Você está na página 1de 15

Capítulo 2

Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.

Lista ligada

A representação de um conjunto de dados, por exemplo, um grupo


de clientes de uma empresa, é uma necessidade comum a diversos sis-
temas de computação. A estrutura básica vetor, por exemplo, pode ser
utilizada em várias aplicações, entretanto o uso de vetores implica a
declaração do número máximo de elementos, e isso pode ser um limi-
tador, pois nem sempre o número máximo de elementos do conjunto é
conhecido, e muitas vezes esse número pode resultar em desperdício
de recursos, com a alocação desnecessária de memória (GOODRICH;
TAMASSIA, 2013).

17
Uma solução seria a utilização de estruturas de dados que possibi-

Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.
litam a variação do número de elementos de acordo com a necessida-
de, permitindo aumentar e diminuir o número de elementos conforme
a necessidade da aplicação e oferecendo alternativas para implemen-
tação computacional de problemas como o cadastro de clientes de
uma empresa.

Neste capítulo, abordaremos o conceito de lista ligada, as técnicas


de implementação utilizando a linguagem Java que viabilizam o fun-
cionamento de listas ligadas e um conjunto de operações sobre esse
tipo de estrutura de dados.

1 Conceito de lista ligada


A lista ligada é uma estrutura de dados composta por um conjun-
to de elementos, denominados “nós”, organizados e encadeados em
sequência, e que pode ser representado como um tipo abstrato de
dados (GOODRICH; TAMASSIA, 2013; TENENBAUM; LANGSAM;
AUGENSTEIN, 1995).

Ela pode ser aplicada em diversos problemas computacionais, prin-


cipalmente naqueles em que não se sabe o tamanho do conjunto de
dados. Vamos tomar como exemplo um conjunto de equipamentos au-
tônomos, alimentados por energia solar, que são destinados a coletar a
umidade do terreno e são instalados em vários pontos de uma fazenda
no interior do país. O software de controle desse equipamento preci-
sa armazenar as amostragens continuamente até que os dados sejam
coletados por um funcionário, que circula periodicamente pela fazenda
com um aparelho coletor de dados. O sistema do equipamento pode ser
implementado com uma lista ligada para armazenar as diversas amos-
tragens de umidade.

18 Estrutura de dados
A figura 1 ilustra a representação gráfica de uma lista ligada imple-
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.

mentada como uma sequência de nós encadeados, na qual a variável


início aponta para o primeiro nó, e, assim sucessivamente, um nó apon-
ta para o próximo, até que o último nó aponte para um valor nulo, indi-
cando o final da lista.

Figura 1 – Representação gráfica de uma lista ligada

Início Nó 1 Nó 2 Nó 3 ... Nó n

No caso de uma lista ligada vazia, ou seja, que não apresenta ne-
nhum elemento, o início aponta para um valor nulo, conforme apresen-
tado na figura 2. A lista vazia é, geralmente, o estado inicial de criação
de uma lista ligada, além disso, é um estado a ser testado em diversas
situações computacionais; por exemplo, ao remover um elemento da
lista ligada, o estado de lista vazia deve sempre ser testado.

Figura 2 – Lista ligada vazia

Início

O código a seguir implementa a classe No, caracterizada como um


TAD, contendo os campos elemento e proximo, implementando as ope-
rações necessárias para a manipulação desses nós, incluindo método
para construção dos objetos “nó”, atribuição dos campos (elemento e
próximo) e recuperação do objeto atribuído ao campo elemento do nó.

Lista ligada 19
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.
// Implementação da classe No

public class No

private No proximo; // aponta para o próximo No da Lista

private Object elemento; // armazena o elemento de cada No

public No(Object elemento, No proximo) // construtor classe No

this.elemento = elemento;

this.proximo = proximo;

public void setProximo(No proximo) // método que altera próximo No da Lista

this.proximo = proximo;

public No getProximo() // método que recebe o próximo No da Lista

return proximo;

public void setElemento(Object elemento) // método para alterar o elemento

this.elemento = elemento;

public Object getElemento() // método para receber o objeto contido no No

return elemento;

// Final da classe No

Cabe observar que a variável elemento de cada nó é um objeto gené-


rico (tipo Object de Java) que pode armazenar qualquer tipo de objeto,
inclusive os associados a um cadastro de clientes. O trecho de código
Java a seguir apresenta a classe Lista, que representa uma primeira ver-
são do TAD lista ligada:

20 Estrutura de dados
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.

// Implementação da classe Lista

public class Lista

private No inicio;

public Lista() // construtor da classe Lista inicializada vazia

this.inicio = null;

// Final da classe Lista

A implementação do TAD lista ligada ainda deve apresentar um con-


junto de operações que viabilizam a manipulação da classe Lista e que
serão implementadas na próxima seção deste capítulo:

• Inserção de um elemento no início da Lista.

• Remoção de um elemento no início da Lista.

• Busca por um determinado elemento da Lista.

• Busca por um elemento em determinada posição da Lista.

• Listagem de todos os elementos da Lista.

• Esvaziamento completo da Lista.

Por exemplo, no tratamento do cadastro de uma lista de clientes,


cada nó pode conter os dados de cliente, e a lista ligada deve armazenar
o conjunto de dados dos clientes da empresa. O código em linguagem
Java a seguir apresenta a implementação da classe Cliente contendo os
atributos (razão social, endereço e previsão de vendas), o construtor da
classe e os métodos para operação dos atributos (atualiza a previsão de
vendas e mudança de endereço).

Lista ligada 21
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.
// Implementação da classe Cliente

public class Cliente

private long codigo;

private String razaoSocial;

private String endereco;

private double previsaoVendas;

public Cliente(long c, String r, String e, double p) // construtor classe Cliente

codigo = c;

razaoSocial = r;

endereco = e;

previsaoVendas = p;

public String toString()

return ″Codigo: ″+codigo+″ Razão Social: ″+razaoSocial;

public void atualizaRazaoSocial(String r)

razaoSocial = r;

public void atualizaPrevisao(double p )

previsaoVendas = p;

public void mudaEndereco (String e )

endereco = e;

// Final da classe Cliente

Observe que “no Java, a hierarquia de classes inicia com a classe


Object” (DEITEL; DEITEL, 2010, p. 284), ou seja, um objeto instanciado da
classe No poderá conter no atributo elemento a classe Cliente. Na próxi-
ma seção, serão abordadas as operações oferecidas pela lista ligada e
a utilização da classe cliente como elemento do nó da lista.

22 Estrutura de dados
2 Operações de adição e remoção de nós
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.

O modo mais simples de adição de elementos em uma lista liga-


da é a inserção de um novo elemento no início da lista (GOODRICH;
TAMASSIA, 2013). A figura 3 apresenta os passos para realizar esse
procedimento, sendo que, nessa operação, basta criar um novo nó
(passo 1) com o elemento desejado, atribuir ao atributo próximo o início
atual da lista (passo 2) e, em seguida, atribuir ao início da lista o novo nó
criado (passo 3) (TENENBAUM; LANGSAM; AUGENSTEIN, 1995).

Figura 3 – Inserção de elemento no início da lista ligada

Inserção de novo nó Início Nó 1 Nó 2 ... Nó n

Passo 1: Novo nó criado Novo

Passo 2: Ligar novo nó à lista Início Nó 1 Nó 2 ... Nó n

Passo 3: Início ligado ao novo nó Início Novo Nó 1 Nó 2 ... Nó n

A implementação da operação de inserção no início da lista ligada


também é simples e apresentada na nova versão da classe Lista a se-
guir. Cabe observar, no código, os comentários relacionando as linhas
de comando com os passos descritos na figura 3.

// Implementação da classe Lista com o método para inserção no início

public class Lista

private No inicio;

public Lista() // construtor da classe Lista inicializada vazia

Lista ligada 23
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.
{
this.inicio = null;
}
public void insereInicio(Object elemento)
{
No novoNo = new No(elemento, null); // passo 1 da figura 3
novoNo.setProximo(this.inicio); // passo 2 da figura 3
this.inicio = novoNo; // passo 3 da figura 3
}
}
// Final da classe Lista

A remoção de elementos no início de uma lista ligada também


é o modo mais simples de implementação desse tipo de operação
(GOODRICH; TAMASSIA, 2013). Os passos para realizar a operação
de remoção no início da lista ligada são apresentados na figura 4. O
passo 1 é fazer uma cópia do início da lista. Em seguida, no passo 2,
o início passa a ser ligado ao próximo elemento da lista. Por fim, no
passo 3, o elemento a ser removido é liberado. Cabe ressaltar que esses
passos só podem ser utilizados se a lista ligada apresentar pelo menos
um elemento, ou seja, não for uma lista ligada vazia.

Figura 4 – Remoção de elemento no início da lista ligada

Remoção de nó inicial
Passo 1:
Variável auxiliar copia início Início Nó 1 Nó 2 ... Nó n
Auxiliar

Passo 2:
Início ligado ao próximo nó Nó 1 Nó 2 ... Nó n
Auxiliar Início

Passo 3:
O nó ligado a auxiliar é liberado Início Nó 2 ... Nó n

Auxiliar

24 Estrutura de dados
Semelhante à implementação da operação de inserção no início da
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.

lista ligada, o método para remoção de um nó do início também é bas-


tante simples e está representado em uma nova versão da classe Lista.
Os comentários no código nas linhas de comando estão relacionados
com os passos descritos na figura 4.

// Implementação da classe Lista com os métodos inserção e remoção no início


public class Lista
{
private No inicio;
public Lista() // construtor da classe Lista inicializada vazia
{
this.inicio = null;
}
public void insereInicio(Object elemento)
{
No novoNo = new No(elemento, null); // passo 1 da figura 3
novoNo.setProximo(this.inicio); // passo 2 da figura 3
this.inicio = novoNo; // passo 3 da figura 3
}
public Object removeInicio()
{
No auxiliar = this.inicio; // passo 1 da figura 4
this.inicio = auxiliar.getProximo(); // passo 2 da figura 4
return auxiliar.getElemento(); // passo 3 da figura 4
}
}
// Final da classe Lista

Tomando como referência a versão anterior da classe Lista, o códi-


go a seguir apresenta a classe CadastroCliente, que exemplifica como
cadastros de clientes são inseridos e removidos da lista ligada e, tam-
bém, o pleno funcionamento de um tipo abstrato de dados, no qual os
dados estão encapsulados e são acessados apenas pelas operações
disponibilizadas.

Lista ligada 25
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.
// Exemplo de inserção e remoção de cadastros de clientes

public class CadastroCliente

public static void main(String[] args)

Lista listaClientes = new Lista(); // cria a lista de clientes

Cliente c = new Cliente(221,″Produtos excelentes LTDA″,

″Rua sem fim, 200″,

5000.0);

// inserindo elementos na Lista Ligada

listaClientes.insereInicio(c); // usando uma variável cliente

listaClientes.insereInicio(new Cliente(185,″Negócios Importantes SA″,

″Avenida Principal, 10″,

12000.0));

listaClientes.insereInicio(new Cliente(443,″Parceiros Críticos LTDA″,

″Rua dos negócios, 2000″,

7000.0));

// removendo um elemento da Lista Ligada

// necessário type casting para a classe Cliente

Cliente clienteRemovido = (Cliente) listaClientes.removeInicio();

System.out.println(clienteRemovido);

// final da classe CadastroCliente

As operações de inserção e remoção implementadas são essenciais


para o funcionamento de uma lista ligada. Uma operação adicional in-
teressante de ser implementada é a operação de listagem de toda a
lista ligada. O trecho de código em Java a seguir apresenta o método
imprimeLista, que será incorporado à classe Lista.

public void imprimeLista() // método para imprimir todo o conteúdo da lista

No auxiliar = this.inicio; //auxiliar percorre a lista do início ao fim

System.out.println(″Inicio da Lista Ligada″);

while (auxiliar != null) // testa se ainda não chegou no final da lista

26 Estrutura de dados
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.

System.out.println(auxiliar.getElemento()); // imprime com o método toString

auxiliar = auxiliar.getProximo(); // passa para o próximo Nó da lista

System.out.println(″Final da Lista Ligada″);

Cabe observar que o método imprimeLista apresenta uma estrutura


de programação que percorre toda a lista utilizando a variável auxiliar,
que recebe o início da lista. Enquanto essa variável auxiliar não chegar
ao final da lista (auxiliar for diferente de null), o elemento do nó é im-
presso e a variável auxiliar recebe o próximo nó da lista (GOODRICH;
TAMASSIA, 2013; LAFORE, 2004).

O algoritmo para percorrer uma lista ligada pode ser aplicado em


diversas operações, por exemplo, a busca de um elemento na lista ou
para esvaziar totalmente a lista eliminando todos os nós que a com-
põem. A última versão da classe Lista apresenta métodos adicionais
(buscaElemento e liberaLista, respectivamente), que desempenham es-
sas novas operações, e incorpora também o método imprimeLista.

// Implementação da classe Lista com os métodos inserção e remoção no início

public class Lista


{
private No inicio;
public Lista() // construtor da classe Lista inicializada vazia
{
this.inicio = null;
}
public void insereInicio(Object elemento)
{
No novoNo = new No(elemento, null); // passo 1 da figura 3
novoNo.setProximo(this.inicio); // passo 2 da figura 3
this.inicio = novoNo; // passo 3 da figura 3

Lista ligada 27
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.
}
public Object removeInicio()
{
No auxiliar = this.inicio; // passo 1 da figura 4
this.inicio = auxiliar.getProximo(); // passo 2 da figura 4
return auxiliar.getElemento(); // passo 3 da figura 4
}
public void imprimeLista() // método para imprimir todo o conteúdo da lista
{
No auxiliar = this.inicio; //auxiliar percorre a lista do início ao fim
System.out.println(″Inicio da Lista Ligada″);
while (auxiliar != null) // testa se ainda não chegou no final da lista
{
System.out.println(auxiliar.getElemento()); //imprime com o método toString
auxiliar = auxiliar.getProximo(); // passa para o próximo Nó da lista
}
System.out.println(″Final da Lista Ligada″);
}
public Object buscaElemento(long posicao) // busca o elemento na posição da lista
{
No auxiliar= this.inicio;
while ((posicao > 0) && (auxiliar != null))
{
if (posicao == 1)
return auxiliar.getElemento();
posicao--;
auxiliar = auxiliar.getProximo(); // passa para o próximo Nó da lista
}
return null; // a lista não possui elemento na posição indicada
}
public void liberaLista() // libera todos os nós da lista
{
while (inicio != null)
{
inicio = inicio.getProximo();
// o garbage collector de Java libera automaticamente o nó eliminado
}
}
}
// Final da classe Lista

28 Estrutura de dados
Por fim, utilizando essa última versão da classe Lista, o código a se-
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.

guir exemplifica a utilização das operações oferecidas pelo TAD lista.

// Exemplo de inserção e remoção de cadastros de clientes


public class CadastroCliente
{
public static void main(String[] args)
{
Lista listaClientes = new Lista(); // cria a lista de clientes
listaClientes.imprimeLista();
Cliente c = new Cliente(221,″Produtos excelentes LTDA″,
″Rua sem fim, 200″,
5000.0);

// inserindo elementos na Lista Ligada

listaClientes.insereInicio(c); // usando uma variável cliente

listaClientes.imprimeLista();

listaClientes.insereInicio(new Cliente(185,″Negócios Importantes SA″,

″Avenida Principal, 10″,

12000.0));

listaClientes.imprimeLista();

listaClientes.insereInicio(new Cliente(443,″Parceiros Críticos LTDA″,

″Rua dos negócios, 2000″,

7000.0));

listaClientes.imprimeLista();

// busca do elemento na posição 2 da lista

c = (Cliente) listaClientes.buscaElemento(2);

if (c != null)

System.out.println(″Elemento da posicao 2 da Lista Ligada″);

System.out.println(c);

// removendo um elemento da Lista Ligada

// necessário type casting para a classe Cliente

Cliente clienteRemovido = (Cliente) listaClientes.removeInicio();

System.out.println(″Elemento removido da Lista Ligada″);

System.out.println(c);

listaClientes.imprimeLista();

// liberando toda a lista

System.out.println(″Liberando toda a lista″);

Lista ligada 29
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.
listaClientes.liberaLista();

listaClientes.imprimeLista();

// final da classe CadastroCliente

Considerações finais
Neste capítulo, foram apresentados os conceitos associados a listas
ligadas e como implementar esses tipos abstratos de dados. As opera-
ções de inserção, remoção, busca, listagem e liberação de elementos da
lista foram exemplificadas em aplicações e explicadas passo a passo,
para um completo entendimento dos algoritmos de implementação.

Cabe ressaltar que os conceitos associados a alocação de dinâmica,


encapsulamento, tratamento de ponteiros e diversas estruturas básicas
de programação foram apresentados visando oferecer recursos de pro-
gramação fundamentais para o desenvolvimento de sistemas compu-
tacionais e fornecer insumos para os estudos abordados nos demais
capítulos deste livro.

PARA SABER MAIS

Existem variações de implementação e operações sobre listas ligadas,


por exemplo, listas duplamente encadeadas, listas circulares, listas or-
denadas, listas de prioridades e coleções, que podem ser estudadas em
nas obras de Deitel e Deitel (2010), Goodrich e Tamassia (2013), Lafore
(2004) e Szwarcfiter e Markenzon (2010).

30 Estrutura de dados
Referências
Material para uso exclusivo de aluno matriculado em curso de Educação a Distância da Rede Senac EAD, da disciplina correspondente. Proibida a reprodução e o compartilhamento digital, sob as penas da Lei. © Editora Senac São Paulo.

DEITEL, Paul J. Y.; DEITEL, Harvey M. Como programar Java. 10. ed. São Paulo:
Pearson, 2010.

GOODRICH, Michael T.; TAMASSIA, Roberto. Estrutura de dados e algoritmos


em Java. 5. ed. Porto Alegre: Bookman, 2013.

LAFORE, Robert. Estrutura de dados e algoritmos em Java. Rio de Janeiro:


Ciência Moderna, 2004.

SZWARCFITER, Jayme Luiz; MARKENZON, Lilian. Estruturas de dados e seus


algoritmos. Rio de Janeiro: LTC, 2010.

TENENBAUM, Aaron M.; LANGSAM, Yedidyah; AUGENSTEIN, Moshe J.


Estruturas de dados usando C. São Paulo: Makron Books, 1995.

Lista ligada 31

Você também pode gostar