Upload
doankien
View
215
Download
1
Embed Size (px)
Citation preview
COLÉGIO ESTADUAL ULYSSES GUIMARÃES
CURSO TÉCNICO PROFISSIONALIZANTE EM INFORMÁTICA
ERINALDO SANCHES NASCIMENTO
TIPO ABSTRATO DE DADOS:
LISTAS ENCADEADAS
FOZ DO IGUAÇU
2013
i
LISTA DE QUADROS
QUADRO 1 – DEFINIÇÃO DA CLASSE NO1 .............................................................. 3
QUADRO 2 – DEFINIÇÃO DA CLASSE DE LISTA ENCADEADA ............................... 5
QUADRO 3 – DEMONSTRAÇÃO DE UMA LISTA ENCADEADA ............................... 7
QUADRO 4 – LISTA ENCADEADA COM UMA CLASSE NO INTERNA. ..................... 8
QUADRO 5 – LISTA ENCADEADA GENÉRICA .......................................................... 9
QUADRO 6 – DEFINIÇÃO DA CLASSE DE ENTRADA............................................. 13
QUADRO 7 – APLICAÇÃO USANDO LISTA ENCADEADA GENÉRICA................... 14
ii
SUMÁRIO
10 LISTAS ................................................................................................................... 1 10.1 TIPOS ABSTRATOS DE DADOS (TAD) ....................................................................... 1 10.1.1 TAD Lista .......................................................................................................... 2 10.1.2 Classe de Lista Encadeada .............................................................................. 2 10.1.2.1 A Classe Nó .................................................................................................. 3 10.1.2.2 Classe Lista Encadeada ................................................................................ 4 10.1.2.3 Demonstração da Classe de Lista Encadeada .............................................. 7 10.1.2.4 Classe Nó Interna .......................................................................................... 8 10.1.2.5 Classe Genérica de Lista Encadeada ........................................................... 8 10.1.2.6 Classe Entrada para Dados de uma Lista Encadeada Genérica ................ 13 10.1.2.7 Demonstração de uma Lista Encadeada Genérica ..................................... 14 10.2 EXERCÍCIOS ......................................................................................................... 15 10.3 REFERÊNCIAS BIBLIOGRÁFICAS ............................................................................. 17
1
10 LISTAS
O pacote java.util contém uma grande variedade de classes e interfaces que
suportam uma ampla gama de funcionalidades. Por exemplo, a estrutura das
coleções.
Uma coleção é uma estrutura de dados – na verdade, um objeto – que pode
conter referências a outros objetos. Normalmente, coleções contêm referências a
objetos que são todos do mesmo tipo. A Tabela 1 lista algumas das interfaces do
framework coleções.
Interface Descrição
Coleção A interface raiz na hierarquia de coleções a partir das quais as
interfaces Conjunto, Fila e Lista são derivadas.
Conjunto Uma coleção que não contém duplicatas.
Lista Uma coleção ordenada que pode conter elementos duplicados.
Mapa Uma coleção que associa chaves a valores e não podem conter
chaves duplicadas.
Fila Normalmente uma coleção first-in (primeiro a entrar), first-out
(primeiro a sair).
Tabela 1 – Algumas interfaces do framework colletions.
10.1 TIPOS ABSTRATOS DE DADOS (TAD)
Um tipo abstrato de dado (TAD) é um conjunto de objetos, juntamente com
um conjunto de operações. Tipos abstratos de dados são abstrações matemáticas.
Objetos tais como listas, conjuntos, e gráficos, juntamente com suas operações,
podem ser vistos como tipos abstratos de dados, como números inteiros, reais e
booleanos são tipos de dados.
2
10.1.1 TAD Lista
Considere uma lista geral de forma A0, A1, A2,..., An-1. Onde o tamanho da
lista é n. Se uma lista estiver vazia seu tamanho é 0 (zero).
Para qualquer lista, exceto a lista vazia, Ai sucede Ai-1 (i <n) e que Ai-1
precede Ai (i> 0). O primeiro elemento da lista é A0, e o último elemento é An-1. A
posição do elemento Ai em uma lista é i.
Associado a estas definições um conjunto de operações é realizada na lista
TAD, como: imprimir, esvaziar, procurar (retorna a posição da primeira ocorrência de
um item), inserir e remover. Poderia ser acrescentadas ainda, operações como
próxima e anterior, que retorna a posição do sucessor e predecessor,
respectivamente.
10.1.2 Classe de Lista Encadeada
Uma lista encadeada é uma estrutura de dados ligada que consiste numa
cadeia única de nós, cada um está conectado ao seguinte por uma ligação. Este é o
tipo mais simples de estrutura de dados encadeado, mas é, no entanto, amplamente
utilizada.
Figura 1 – Exemplo de lista simplesmente encadeada.
Fonte: http://pt.wikipedia.org/wiki/Lista_simplesmente_ligada.
A Figura 1 é um diagrama de uma lista encadeada. Em Java, um nó é um
objeto de alguma classe nó. Cada nó tem um lugar (ou lugares) para alguns dados e
um lugar para manter um link para outro nó. Os links são mostrados como setas que
3
apontam para o nó seguinte. Em Java, as ligações serão implementadas como
referências a um nó armazenado em uma variável de instância do tipo de nó.
10.1.2.1 A Classe Nó
A classe No1, no Quadro 1 é definida especificando, entre outras coisas,
uma variável de instância do tipo No1 chamada link. Isto permite que cada nó
armazene uma referência a outro nó do mesmo tipo.
O primeiro nó em uma lista encadeada é chamado de nó cabeça.
Começando no nó principal, é possível percorrer toda a lista encadeada, visitando
cada nó exatamente uma vez. A cabeça é uma variável do tipo No1 que contém uma
referência para o primeiro nó na lista encadeada – isto é, uma referência para o nó
principal. A função da variável cabeça é permitir que o código verifique o primeiro nó
ou cabeça.
Quadro 1 – Definição da classe No1
1 package listaencadeada;
2 public class No1 {
3 private String item;
4 private int cont;
5 private No1 link;//um nó contém uma referência para outro nó.
6 public No1(){
7 link = null;
8 item = null;
9 cont = 0;
10 }
11 public No1(String novoItem, int novoCont, No1 valorLink){
12 setDado(novoItem, novoCont);
13 link = valorLink;
14 }
15 public void setDado(String novoItem, int novoCont){
16 item = novoItem;
4
17 cont = novoCont;
18 }
19 public void setLink(No1 novoLink){
20 link = novoLink;
21 }
22 public String getItem(){
23 return item;
24 }
25 public int getCont(){
26 return cont;
27 }
28 public No1 getLink(){
29 return link;
30 }
31 }
10.1.2.2 Classe Lista Encadeada
Em Java, uma lista encadeada é um objeto. O Quadro 2 contém uma
definição de uma classe de lista encadeada.
Um objeto de lista encadeada não contém diretamente todos os nós da lista
encadeada. Contém apenas a variável de instância head que faz uma referência ao
primeiro nó.
Cada nó pode ser alcançado a partir deste primeiro nó. A variável de
instância link do primeiro e cada No1 da lista encadeada contém uma referência ao
No1 seguinte na lista encadeada. Assim, as setas representadas na Figura 1 são
compreendidas como referências em Java. Cada objeto do nó de uma lista
encadeada contém (na sua variável de instância link) uma referência a outro objeto
da classe No1, e este outro objeto contém uma referência a outro objeto da classe
No1, e assim por diante até ao fim da lista encadeada.
5
Quadro 2 – Definição da classe de lista encadeada
1 package listaencadeada;
2 public class ListaEncadeada1 {
3 private No1 head;
4 public ListaEncadeada1(){
5 head = null;
6 }
7 /*
8 * Adiciona um nó no início da lista, com os dados especificados.
9 * O nó adicionado será o primeiro nó na lista.
10 */
11 public void addInicio (String nomeItem, int contItem){
12 head = new No1(nomeItem, contItem, head);
13 }
14 /*
15 * Remove o nó principal e retorna true se a lista contém pelo menos um
nó.
16 * Retorna false se a lista está vazia.
17 */
18 public boolean excluiNoHead(){
19 if (head != null){
20 head = head.getLink();
21 return true;
22 }
23 Else
24 return false;
25 }
26 public int tamanho(){
27 int cont = 0;
28 No1 posicao = head;
29 while (posicao != null){//o último nó é indicado pelo valor nulo.
30 cont++;
31 posicao = posicao.getLink();
6
32 }
33 return cont;
34 }
35 public boolean contem(String item){
36 return (procura(item) != null);
37 }
38 /*
39 * Localiza o primeiro nó que contém o item de destino,
40 * e retorna uma referência a esse nó.
41 * Se o alvo não estiver na lista, retorna nulo.
42 */
43 private No1 procura(String alvo){
44 No1 posicao = head;
45 String posicaoItem;
46 while (posicao != null){
47 posicaoItem = posicao.getItem();
48 if (posicaoItem.equals(alvo))
49 return posicao;
50 posicao = posicao.getLink();
51 }
52 return null;//alvo não encontrado
53 }
54 public void imprimeLista(){
55 No1 posicao = head;
56 while (posicao != null){
57 System.out.println(posicao.getItem()+" "
58 + posicao.getCont());
59 posicao = posicao.getLink();
60 }
61 }
62 }
7
10.1.2.3 Demonstração da Classe de Lista Encadeada
O Quadro 3 contém um programa simples que demonstra como alguns dos
métodos na classe ListaEncadeada1 se comportam.
Quadro 3 – Demonstração de uma lista encadeada
1 package listaencadeada;
2 public class ListaEncadeadaDemo {
3 public static void main(String[] args) {
4 ListaEncadeada1 lista = new ListaEncadeada1();
5 lista.addInicio("Maçã", 1);
6 lista.addInicio("Bananas", 2);
7 lista.addInicio("Melão", 3);
8 System.out.println("A lista tem "+lista.tamanho()
9 +" nós");
10 lista.imprimeLista();
11 if (lista.contem("Melão"))
12 System.out.println("Melão está na lista.");
13 else
14 System.out.println("Melão não está na lista.");
15 lista.excluiNoHead();
16 if (lista.contem("Melão"))
17 System.out.println("Melão está na lista");
18 else
19 System.out.println("Melão não está na lista");
20 while (lista.excluiNoHead());
21 System.out.println("Início da lista: ");
22 lista.imprimeLista();
23 System.out.println("Fim da lista.");
24 }
25 }
8
10.1.2.4 Classe Nó Interna
É possível fazer uma lista encadeada, ou qualquer outra estrutura de dados
semelhante, autossuficiente, tornando a classe nó uma classe interna. Fazendo,
assim, a classe ListaEncadeada mais autônoma. O Quadro 4 apresenta a classe
ListaEncadeada2 com um classe No interna.
Quadro 4 – Lista encadeada com uma classe No interna.
public class ListaEncadeada2 {
private class No {//início da classe No interna
private String item;
private No link;
public No(){
link = null;
item = null;
}
public No(String novoItem, No valorLink){
item = novoItem;
link = valorLink;
}
}//fim da classe No interna
private No head;
public ListaEncadeada2(){
head = null;
}
10.1.2.5 Classe Genérica de Lista Encadeada
O Quadro 5 mostra uma lista encadeada genérica com um parâmetro do tipo
T para o tipo de dados armazenados em um nó. Esta lista genérica ligada tem os
mesmos métodos, codificados basicamente da mesma forma, como a lista
9
encadeada do Quadro 4, mas foi utilizado um parâmetro de tipo para o tipo de dados
dos nós.
Quadro 5 – Lista encadeada genérica
1 package listaencadeada;
2 public class ListaEncadeadaGenerica<T> {
3 . private class No<T>{//classe No<T> interna
4 private T dado;
5 private No<T> link;
6 public No(){
7 dado = null;
8 link = null;
9 }
10 public No(T novoDado, No<T> valorLink){
11 dado = novoDado;
12 link = valorLink;
13 }
14 }//fim da classe No<T> interna
15 private No<T> head;
16 public ListaEncadeadaGenerica(){//construtor
17 head = null;
18 }
19 /*
20 * Adiciona um nó no início da lista, com os dados especificados.
21 * O nó adicionado será o primeiro nó na lista.
22 */
23 public void addInicio(T itemDado){
24 head = new No<T> (itemDado, head);
25 }
26 /*
27 * Remove o nó principal
28 * e retorna true se a lista contém pelo menos um nó.
29 * Retorna false se a lista está vazia.
30 */
10
31 public boolean excluiNo(){
32 if (head != null){
33 head = head.link;
34 return true;
35 }
36 else
37 return false;
38 }
39 //Retorna o número de nós na lista.
40 public int tamanho(){
41 int cont = 0;
42 No<T> posicao = head;
43 while (posicao != null){
44 cont++;
45 posicao = posicao.link;
46 }
47 return cont;
48 }
49 public boolean contem(T item){
50 return (procura(item) != null);
51 }
52 /*
53 * Localiza o primeiro nó que contém o item de destino,
54 * e retorna uma referência a esse nó.
55 * Se o alvo não estiver na lista, retorna nulo.
56 */
57 private No procura(T alvo){
58 No<T> posicao = head;
59 T posicaoItem;
60 while (posicao != null){
61 posicaoItem = posicao.dado;
62 //o tipo T deve ter um método equal bem definido
para esse método funcionar.
11
63 if (posicaoItem.equals(alvo))
64 return posicao;
65 posicao = posicao.link;
66 }
67 return null;//alvo não encontrado.
68 }
69 /*
70 * Localiza o primeiro nó que contém o alvo
71 * e retorna uma referência para os dados em que o nó.
72 * Se o alvo não estiver na lista, nulo é retornado.
73 */
74 private T encontraDado(T alvo){
75 No<T> resultado = procura(alvo);
76 if (resultado == null)
77 return null;
78 Else
79 return resultado.dado;
80 }
81 public void imprimeLista(){
82 No<T> posicao = head;
83 while (posicao != null){
84 System.out.println(posicao.dado);
85 posicao = posicao.link;
86 }
87 }
88 public boolean vazio(){
89 return (head == null);
90 }
91 public void limpa(){
92 head = null;
93 }
94 /*
95 * Para duas listas serem iguais devem conter
12
96 * os mesmos itens de dados na mesma ordem.
97 * De igual modo T é usado para comparar itens de dados.
98 */
99 public boolean igual(Object outroObjeto){
100 if (outroObjeto == null)
101 return false;
102 else if (getClass() != outroObjeto.getClass())
103 return false;
104 else {
105 ListaEncadeadaGenerica<T> outraLista =
106 (ListaEncadeadaGenerica<T>) outroObjeto;
107 if (tamanho() != outraLista.tamanho())
108 return false;
109 No<T> posicao = head;
110 No<T> outraPosicao = outraLista.head;
111 while (posicao != null){
112 if (! (posicao.dado.equals
(outraPosicao.dado)) )
113 return false;
114 posicao = posicao.link;
115 outraPosicao = outraPosicao.link;
116 }
117 return true;
118 }
119 }
120 }
A lista encadeada apresentada no Quadro 2 não tem um método igual, para
manter os exemplos simples e não prejudicar a mensagem principal. No entanto,
uma classe de lista encadeada normalmente deve ter um método igual.
Existe mais que uma abordagem para a definição de um método igual para
uma lista encadeada. Os mais óbvios são:
13
1. Duas listas encadeadas são iguais se contêm as mesmas entradas de dados
(possivelmente em ordem diferente).
2. Duas listas encadeadas são iguais se contiverem as mesmas entradas de dados
na mesma ordem, isto é, os dados do primeiro nó do objeto de chamada forem
iguais ao de dados no primeiro nó da outra lista encadeada, os dados nos dois
nós segundo são iguais, e assim por diante.
10.1.2.6 Classe Entrada para Dados de uma Lista Encadeada Genérica
O programa de demonstração exibido no Quadro 7 usa a entrada da classe,
definida no Quadro 6, como o tipo conectado para o parâmetro de tipo T.
Quadro 6 – Definição da classe de entrada
1 package listaencadeada;
2 public class Entrada {
3 private String item;
4 private int cont;
5 public Entrada(String itemDado, int contDado){
6 item = itemDado;
7 cont = contDado;
8 }
9 public String toString(){
10 return (item + " "+ cont);
11 }
12 public boolean igual(Object outroObjeto){
13 if (outroObjeto == null)
14 return false;
15 else if (getClass() != outroObjeto.getClass())
16 return false;
17 else{
18 Entrada outraEntrada = (Entrada)outroObjeto;
19 return (item.equals(outraEntrada.item)
14
20 && (cont == outraEntrada.cont));
21 }
22 }
23 }
Quando da definição da classe ListaEncadeadaGenerica<T> no Quadro 5, o
tipo de um nó é o No<T>, não é No. Se <T> for omitido, sua aplicação pode ou não
receber uma mensagem de erro do compilador, dependendo de outros detalhes do
código. O problema é que No realmente significa algo semelhante a um nó com
dados tipo objeto, em vez de tipo de dados T. Se o compilador exibir uma
mensagem de erro desconcertante, procure um <T> desaparecido.
Às vezes, uma mensagem de aviso do compilador pode ser útil ao se
cometer esse erro. Ao receber um aviso de que menciona uma conversão tipo de No
a No<T>, procure uma <T> omitido.
10.1.2.7 Demonstração de uma Lista Encadeada Genérica
A Quadro 7 demonstra o programa para uma lista encadeada genérica.
Quadro 7 – Aplicação usando lista encadeada genérica
1 package listaencadeada;
2
3 public class ListaEndadeadaGenericaDemo {
4 public static void main(String[] args) {
5 ListaEncadeadaGenerica<Entrada> lista = new
ListaEncadeadaGenerica<Entrada>();
6 Entrada entrada1 = new Entrada("Maçã", 1);
7 lista.addInicio(entrada1);
8 Entrada entrada2 = new Entrada("Banana", 2);
9 lista.addInicio(entrada2);
10 Entrada entrada3 = new Entrada("Melão", 3);
11 lista.addInicio(entrada3);
15
12 System.out.println("A lista tem "+lista.tamanho()
13 + " nós");
14 lista.imprimeLista();
15 System.out.println("Fim da lista");
16 }
17 }
10.2 EXERCÍCIOS
1. Qual a saída é produzida pelo seguinte código?
ListaEncadeada1 lista = new ListaEncadeada1();
lista.addInicio(“Torta de maçã”, 1);
lista.addInicio(“Cachoro quente”, 12);
lista.addInicio(“mostarda”, 1);
lista.imprimeLista();
2. Defina um método chamado Vazio a classe ListaEncadeada1 (Quadro 2), que
retorna true se a lista estiver vazia e false se a lista tem pelo menos um nó nela.
3. Defina um método chamado Limpa a classe ListaEncadeada1 (Quadro2). O
método não tem parâmetros e esvazia a lista.
4. Desenvolva um aplicativo chamado SimplesLivroApp que armazene números
distintos de ISBN (por exemplo, integer) de alguns livros usando um lista
encadeada e faça um método para exibi-los em ordem crescente.
5. Defina uma classe chamada Livro que armazene atributos como o título, número
de ISBN, autor, edição, editora e ano de publicação. Forneça os métodos get e
set nessa classe, para acessar esses atributos. Defina uma classe chamada
LivroApp, que contém o método main. Nesta classe criar um livro alguns objetos
com nomes distintos e armazene-os em uma lista encadeada. Desenvolva os
seguintes métodos:
Procurar por título
Procurar por autor
Procurar por editora
16
Cria uma classe Livro que Ordene por ordem crescente do ano de publicação
(use um método de comparação dos dois objetos que retorne um valor
booleano depois de comparar o ano de publicação dos dois objetos de livros).
6. Defina uma classe chamada Conta que contenha os atributos número da conta,
nome do titular da conta, número de identificação do titular da conta, e ano de
abertura de conta. Fornecer os métodos get e set desta classe para acessar os
atributos. Defina uma classe chamada ContaApp, que contém o método main.
Esta classe deve criar uma conta de alguns objetos com números de contas
distintos e armazená-los em uma lista encadeada. O programa deve, então, pedir
o número da conta como a entrada do console e exibir as informações de conta
referente ao número de conta.
7. Defina uma classe chamada Aluno com três atributos, a saber, nome, curso e
ano. Defina uma classe chamada EstudanteApp, que contém um método main.
Crie objetos vários Estudantes com nomes diferentes, cursos, e ano (por
exemplo, 2006, 2007). Adicione-os em uma lista encadeada. Crie métodos para:
Exibir quantos alunos estão matriculados por determinado curso.
Exibir quantos alunos se matricularam em determinado curso em um ano
específico.
8. Dada uma lista, L, e outra lista, P, contendo inteiros classificados em ordem
crescente. A operação printLots(L, P) vai imprimir os elementos em L que se
encontram em posições especificadas pelo P. Por exemplo, se P = 1, 3, 4, 6, os
elementos nas posições 1, 3, 4, e 6, em L são impressos. Escreva os método
printLots(L, P).
9. (CVM – 2010) Assinale a opção correta.
a) Um nodo indicador de janelas armazena um valor especial chamado high
window (HW).
b) Um nodo prioritário é um nodo extra mantido sempre na posição mais
acessada de uma lista encadeada.
c) Um nodo cabeça é um nodo extra mantido sempre na primeira posição de uma
lista encadeada.
d) Um nodo sentinela autoriza o acesso a valores elevados chamados top
values (TV).
e) Um nodo cabeça armazena um valor especial chamado strong head (SH).
17
10. (PJ-PI – 2009) Uma lista ligada é uma estrutura que corresponde a uma
sequência lógica de entradas ou nós. Cada nó armazena a localização do
próximo elemento na sequência, ou seja, de seu nó sucessor. Nessa estrutura,
a) para estabelecer a ligação entre um nó já pertencente a uma lista e um novo
nó, basta fazer com que o novo nó referencie no, camponext, o nó que
anteriormente era referenciado pelo nó original, desde que esse campo não
tenha o valor nulo.
b) a existência de um ponteiro apontando para o 1º elemento e outro para o fim
da lista permite que a inserção ou deleção de dados de um nó que esteja no
meio da lista seja rapidamente executada.
c) enquanto a entrada que determina o topo da lista é mantida em um nó
descritor dessa lista, a entrada que marca o fim da lista é mantida fora do
descritor.
d) o armazenamento de uma lista requer uma área contígua de memória para
permitir a otimização no processamento de criação e remoção de nós da lista.
e) o armazenamento de uma lista não requer uma área contígua de memória.
Como listas são estruturas dinâmicas, normalmente são definidos procedimentos
que permitem criar e remover nós na memória.
11. Julgue se a afirmação abaixo é verdadeira ou falsa:
( ) A principal característica de uma lista encadeada é o fato de o último
elemento da lista apontar para o elemento imediatamente anterior.
12. Desenvolva o projeto a seguir usando uma GUI.
Considere-se um projetista que precisa desenvolver um sistema para automação
da secretaria acadêmica de uma escola, com as seguintes necessidades.
Cadastre em uma lista os nomes dos alunos, o curso atual, e quatro notas.
O usuário do sistema pode querer saber:
o Quantos alunos estão matriculados na escola.
o Quantos alunos estão matriculados por curso.
o A situação dos alunos por curso, se aprovados ou reprovados.
10.3 REFERÊNCIAS BIBLIOGRÁFICAS
18
DEITEL, Paul; DEITEL, Harvey. Java for Programmers. 2nd Ed. Boston: Pearson
Education, Inc., 2012
SAVITCH, Walter. Absolute Java, 5ª ed. New Jersey: Pearson Education, 2012.
WEISS, Mark A. Data Structures and Algorithm Analysis in Java, 3rd Ed. USA:
Pearson2012