implementacao lista em java

13
Aula 3 Lista orientada a objetos e aplicações UNIVALI/UNITINS • SUPERIOR DE TECNOLOGIA • 3º PERÍODO 35 Objetivos Ao final dessa aula, você deve saber como implementar a estrutura de da- dos Lista em Java e entender sua aplicação em problemas computacionais. Pré-requisitos Para essa aula, é necessário o conhecimento da estrutura de dados Lista e de programação orientada a objetos em Java. Introdução Olá! O que você está achando de programar as estruturas de dados em Java? A mudança de linguagem e paradigma de programação para as implementações que estamos fazendo nessa disciplina é um bom exer- cício de programação e de complementação e fixação dos conteúdos de estruturas de dados. Agora, vamos partir para a programação da estrutura de dados Lista, seguindo o mesmo procedimento que utilizamos nas aulas anteriores. Como toda Fila e toda Pilha são Listas, não devemos ter problemas com essa aula. Para finalizar a nossa aula, resolveremos um problema que utilize Lista, verificando como e onde empregar essa estrutura de dados.

Upload: luidne-mota

Post on 03-Jul-2015

2.090 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Implementacao LISTA Em JAVA

Aula 3Lista orientada a objetos e aplicações

UNIVALI/UNITINS • SUPERIOR DE TECNOLOGIA • 3º PERÍODO 35

Objetivos

Ao final dessa aula, você deve saber como implementar a estrutura de da-dos Lista em Java e entender sua aplicação em problemas computacionais.

Pré-requisitos

Para essa aula, é necessário o conhecimento da estrutura de dados Lista e de programação orientada a objetos em Java.

Introdução

Olá! O que você está achando de programar as estruturas de dados em Java? A mudança de linguagem e paradigma de programação para as implementações que estamos fazendo nessa disciplina é um bom exer-cício de programação e de complementação e fixação dos conteúdos de estruturas de dados.

Agora, vamos partir para a programação da estrutura de dados Lista, seguindo o mesmo procedimento que utilizamos nas aulas anteriores. Como toda Fila e toda Pilha são Listas, não devemos ter problemas com essa aula.

Para finalizar a nossa aula, resolveremos um problema que utilize Lista, verificando como e onde empregar essa estrutura de dados.

Page 2: Implementacao LISTA Em JAVA

Figura 1 – Exemplo de Lista dinâmica encadeada e modelo da Classe LISTA

Saiba mais

É importante aprofundar os estudos utilizando livros (DEITEL; DEITEL,

2005) (GOODRICH; TAMASSIA, 2007) (LAFORE, 2004) (PUGA;

RISSETTI, 2003), onde você poderá conhecer outros pontos de vista

sobre o assunto e, conseqüentemente, outras formas de implementar a

estrutura de dados Lista.

36 3º PERÍODO • SUPERIOR DE TECNOLOGIA • UNIVALI/UNITINS

AULA 3 • ESTRUTURA DE DADOS

3.1 Implementação da Classe Lista orientada a objetos

Você lembra o que é uma Lista? A Lista é uma estrutura mais abrangente que a Pilha e a Fila, pois permite operações de entrada e saída em qualquer lugar, como pode ser observado na Figura 1. Conforme fizemos nas aulas anteriores, vamos seguir o modelo apresentado, que é o mesmo da disciplina anterior, e implementar essa idéia em Java com programação orientada a objetos.

Como você já deve ter percebido, a nossa LISTA é composta por elemen-tos (ou itens) da mesma forma que a pilha e a fila das aulas anteriores. A diferença entre a Classe LISTA e as Classes FILA e PILHA são relativas às ope-rações de entrada e saída. Quanto aos atributos desta classe, são iguais aos da PILHA, mas diferem da FILA por não ter o controle de fim. O controle de fim

Page 3: Implementacao LISTA Em JAVA

public class Lista {

// Classe interna a classe Lista, para definir o elemento que compõem a Lista

public class ItemLista {

private Object dado;

private ItemLista prox;

// Construtor, aponta prox do item para null (inicializa item)

public ItemLista() {

this.prox = null;

}

// metodo para atribuir o conteudo ao item da pilha

public void atribuiDado(Object dado){

this.dado = dado;

}

// metodo para retornar o conteudo do item

public Object retornaDado (){

return this.dado;

}

// metodo para atribuir o endereco para onde o item ira apontar

public void atribuiProx(ItemLista proximo){

this.prox = proximo;

}

// metodo para retornar a referencia do próximo item

public ItemLista retornaProx (){

return this.prox;

}

} // fim da classe ItemLista

/** definicao dos atributos da classe LISTA*/

protected ItemLista primeiro;

protected int numeroElementos;

// Construtor da classe fila. Inicializa a fila.

public Lista() {

this.primeiro = null;

this.numeroElementos = 0;

}

// Metodo para inserir um novo item no inicio da Lista

public void insereInicio(Object dado){

ItemLista novoItem = new ItemLista();

novoItem.atribuiDado(dado);

novoItem.atribuiProx(this.primeiro);

this.primeiro = novoItem;

this.numeroElementos ++;

}

AULA 3 • ESTRUTURA DE DADOS

UNIVALI/UNITINS • SUPERIOR DE TECNOLOGIA • 3º PERÍODO 37

da LISTA não é utilizado aqui, para simplificar os controles, uma vez que esse controle só auxiliaria efetivamente para as inserções no fim da LISTA.

A nossa LISTA será um objeto com dois atributos: o PRIMEIRO constitui uma referência ao primeiro elemento (objeto ITEMFILA) e o NUMEROELEMEN-TOS, que armazena a quantidade de elementos da LISTA. Ao instanciarmos o objeto LISTA, o método construtor irá atribuir NULL ao atributo PRIMEIRO, e 0 (zero) ao atributo NUMEROELEMENTOS, fazendo a inicialização da LISTA, como pode ser visto no código apresentado.

Page 4: Implementacao LISTA Em JAVA

// Metodo para remover um item no inicio da Lista

public void removeInicio(){

if (! vazia()){

ItemLista ItemRemovido = this.primeiro ;

this.primeiro = this.primeiro.retornaProx();

this.numeroElementos --;

ItemRemovido = null;

}

}

// Metodo para inserir um item na posição indicada da Lista

public void insereMeio(Object dado, int pos){

// Verifica se Lista esta vazia ou se a insercao e na primeira posicao

if ( vazia() || (pos == 1)){

insereInicio(dado); //insere primeiro item (chama o metodo)

} else {

// se nao estiver vazia continua...

int i = 1;

ItemLista item = this.primeiro; // pega primeiro item da lista

//procurando posicao

while((i < pos-1)&&(item.retornaProx() != null)){

item = item.retornaProx();

i++;

}

//adiciona na lista

ItemLista novoItem = new ItemLista();

novoItem.atribuiDado(dado);

novoItem.atribuiProx(item.retornaProx());

item.atribuiProx(novoItem);

this.numeroElementos ++;

}

}

//remove item pela posicao

public void removeMeio(int pos){

if (pos == 1){

removeInicio(); //remove do inicio (chama o metodo)

} else {

int i = 1;

ItemLista item = this.primeiro;

//procurando posicao

while((i < pos-1)&&(item.retornaProx() != null)){

item = item.retornaProx();

i++;

}

ItemLista ItemRemovido = item.retornaProx();

item.atribuiProx(item.retornaProx().retornaProx());

this.numeroElementos --;

ItemRemovido = null;

}

}

38 3º PERÍODO • SUPERIOR DE TECNOLOGIA • UNIVALI/UNITINS

AULA 3 • ESTRUTURA DE DADOS

Page 5: Implementacao LISTA Em JAVA

//insere item no fim da Lista

public void insereFim(Object dado){

if (! Vazia()) // se lista vazia

this.insereInicio(dado);

else

this.insereMeio(dado,this.numeroElementos + 1);

}

//remove ultimo item da Lista

public void removeFim(){

if (! vazia()){// se lista vazia

if (this.numeroElementos == 1)

this.removeInicio();

else

this.removeMeio(this.numeroElementos);

}

}

//retona dado pela posicao dele na Lista

public Object dadoMeio(int pos){

int i = 1;

ItemLista item = this.primeiro;

//procurando posicao

while((i != pos)&&(item.retornaProx() != null)){

item = item.retornaProx();

i++;

}

return item.retornaDado();

}

//retona primeiro dado da lista

public Object dadoInicio(){

return this.primeiro.retornaDado();

}

//retona ultimo dado da lista

public Object dadoFim(){

return dadoMeio(this.numeroElementos);

}

//retona quantidade de Elementos

public int quantElementos(){

return this.numeroElementos;

}

// Verifica se a lista esta vazia.

public boolean vazia(){

if (this.primeiro == null){

return true;

}else{

return false;

}

}

AULA 3 • ESTRUTURA DE DADOS

UNIVALI/UNITINS • SUPERIOR DE TECNOLOGIA • 3º PERÍODO 39

Page 6: Implementacao LISTA Em JAVA

//mostra todos os dados da Lista

public void Mostra(){

ItemLista aux = this.primeiro;

for(int i=0; i<this.quantElementos(); i++) {

System.out.print(aux.retornaDado() + “ - “);

aux = aux.retornaProx();

}

}

}

40 3º PERÍODO • SUPERIOR DE TECNOLOGIA • UNIVALI/UNITINS

AULA 3 • ESTRUTURA DE DADOS

Como podemos observar no código apresentado, os métodos da LISTA são muito similares aos da PILHA e da FILA. A maior diferença são os métodos de inserção e remoção em uma posição qualquer, que implicam em percorrer a LISTA até encontrar a posição para depois efetuar a inserção ou remoção.

Nos métodos de inserção e remoção numa posição, a implementação permite que estas operações possam ser feitas, inclusive, no início e no fim da LISTA, mesmo que os métodos de inserção e remoção no início e no fim tenham sido feitos. Veja que os métodos insere e remove na posição utilizam o método insere e remove no início, caso a posição seja 1 (um). Como eles também podem inserir ou remover elementos da última posição da LISTA, os métodos insere e remove do fim apenas utilizam estes métodos para fazer a sua função.

Para inserir no fim, basta chamar insere na posição, passando como pa-râmetro a quantidade de elementos da LISTA mais um. Se a LISTA possuir 5 elementos e quisermos inserir mais um no fim da LISTA, ele será o elemento 6, ou seja, quantidade de elementos mais um.

A remoção do fim segue o mesmo princípio, ou seja, basta chamarmos o remove da posição passando a quantidade de elementos da lista, pois esta quantidade corresponde à posição do elemento a ser removido.

Pensando sobre o assunto

Você deve ter percebido que a Classe ITEMFILA é igual à Classe

ITEMPILHA, que é igual à Classe ITEMLISTA. E as operações são

muito similares, pois todas estas estruturas de dados são FILAS. Um

ótimo exercício de programação é reescrever essas classes criando

uma classe LISTA e especializações para PILHA e FILA. Vá em frente

e bom trabalho!

Page 7: Implementacao LISTA Em JAVA

import java.util.Scanner;

import jtads.TADS.Lista;

public class Main {

public Main() {

}

public static void main(String[] args) {

Lista minhaLista = new Lista();

int opcao = 0;

Scanner scn = new Scanner(System.in);

String msg,msg2;

do {

System.out.println(“1) Insere Inicio”);

System.out.println(“2) Insere Posição”);

System.out.println(“3) Insere Fim”);

System.out.println(“4) Remove Inicio”);

System.out.println(“5) Remove Posição”);

System.out.println(“6) Remove Fim”);

System.out.println(“7) Mostra Dados”);

System.out.println(“8) Quantidade Elementos”);

System.out.println(“9) Vazia”);

System.out.println(“10) Mostra o Primeiro”);

System.out.println(“11) Mostra da posição”);

System.out.println(“12) Mostra o Ultimo”);

System.out.println(“0) Sair”);

System.out.println(“Digite a opcao:”);

msg = scn.nextLine();

opcao = Integer.parseInt(msg);

switch(opcao){

case 1:

System.out.println(“Digite o dado: “);

msg = scn.nextLine();

minhaLista.insereInicio(Integer.parseInt(msg));

Break;

case 2:

System.out.println(“Digite o dado: “);

msg = scn.nextLine();

System.out.println(“Digite a posição: “);

msg2 = scn.nextLine();

minhaLista.insereMeio ( Integer.parseInt(msg),

Integer.parseInt(msg2));

break;

case 3:

System.out.println(“Digite o dado: “);

msg = scn.nextLine();

minhaLista.insereFim(Integer.parseInt(msg));

break;

AULA 3 • ESTRUTURA DE DADOS

UNIVALI/UNITINS • SUPERIOR DE TECNOLOGIA • 3º PERÍODO 41

3.2 Utilizando a Classe Lista

Vamos verificar agora como utilizar essa classe. Para fazermos isso, utili-zaremos um programa simples, que permite manipular os elementos da LISTA, utilizando os métodos que implementamos para a Classe LISTA.

Page 8: Implementacao LISTA Em JAVA

case 4:

minhaLista.removeInicio();

break;

case 5:

System.out.println(“Digite a posição: “);

msg2 = scn.nextLine();

minhaLista.removeMeio(Integer.parseInt(msg));

break;

case 6:

minhaLista.removeFim();

break;

case 7:

minhaLista.Mostra();

break;

case 8:

System.out.println( “Quantidade de elementos = “

+minhaLista.quantElementos());

break;

case 9:

if (minhaLista.vazia())

System.out.println(“Fila Vazia!”);

else

System.out.println(“Fila nao Vazia!”);

break;

case 10:

System.out.println( “Primeiro elemento = “

+minhaLista.dadoInicio());

break;

case 11:

System.out.println(“Digite a posição: “);

msg2 = scn.nextLine();

System.out.println (“O elemento “+msg2+” = “

+minhaLista.adoMeio(Integer.parseInt(msg2)));

break;

case 12:

System.out.println( “Ultimo elemento = “

+minhaLista.dadoFim());

break;

}

} while(opcao != 0);

}

}

42 3º PERÍODO • SUPERIOR DE TECNOLOGIA • UNIVALI/UNITINS

AULA 3 • ESTRUTURA DE DADOS

Nesta solução simplificada, feita com o objetivo simples de testar a classe LISTA, instanciamos um objeto LISTA e o usuário pode fazer inserções, remo-ções, mostrar todos os dados da LISTA e outras opções apresentadas no menu de opções, testando, assim, o seu funcionamento.

Page 9: Implementacao LISTA Em JAVA

DADA A SEGUINTE SEQÜÊNCIA DE ENTRADA DE DADOS NO

PROGRAMA:

A SAÍDA PARA ESSES DADOS SERIA A SEGUINTE:

Nome dos soldados: A, B, C, D, E, F, G C é o 1 a sair

Número n= 4 G é o 2 a sair

Nome sorteado para iniciar = G E é o 3 a sair

D é o 4 a sair

F é o 5 a sair

B é o 6 a sair

O Vencedor é o soldado A.

AULA 3 • ESTRUTURA DE DADOS

UNIVALI/UNITINS • SUPERIOR DE TECNOLOGIA • 3º PERÍODO 43

3.3 Aplicações de Lista

Agora que a nossa classe LISTA está testada e funcionando, vamos fazer uma aplicação que utiliza a Classe LISTA. Leia atentamente o enunciado do problema que precisaremos resolver.

Um grupo de soldados precisa pedir reforço no campo de batalha, mas existe somente um cavalo disponível para escapar. Os soldados entram em um acordo para determinar qual deles deverá escapar e trazer ajuda. Eles formam um círculo e um número “n” é sorteado num chapéu. Um de seus nomes é sorteado também. Começando pelo soldado cujo nome foi sorteado, eles começam a contar ao longo do círculo. Quando a contagem alcança “n”, esse soldado é retirado do círculo, e a contagem reinicia com o soldado seguinte.

O processo continua de maneira que, toda vez que “n” é alcançado, outro soldado sai do círculo. Todo soldado sorteado não entra mais na contagem. O último soldado que restar deverá montar no cavalo e escapar. A Figura 2 mostra um exemplo de solução para o problema dos soldados.

Deve ser feito um programa que receba a identificação dos soldados, o valor “n” e a identificação do soldado onde iniciará a contagem, mostrando a seqüência na qual os soldados são eliminados do círculo e o soldado que escapará.

Exemplo:

Page 10: Implementacao LISTA Em JAVA

Figura 2 – Solução para o problema dos soldados.

44 3º PERÍODO • SUPERIOR DE TECNOLOGIA • UNIVALI/UNITINS

AULA 3 • ESTRUTURA DE DADOS

Para solucionar esse problema, podemos utilizar uma lista, armazenando nela o nome (ou identificador) dos soldados. Como pode ser observado na Figura 2, assim como no enunciado, os soldados devem formar um círculo, para facilitar a contagem, pois quando a contagem chega ao último soldado, passa para o primeiro e continua normalmente.

Nossa LISTA pode ser percorrida do início ao fim sem problemas, mas a transição para retornar ao primeiro não é tão natural assim, por isso vamos utilizar uma variação desta LISTA, a LISTA CIRCULAR.

Para fazermos essa lista circular, vamos apenas fazer com que a refe-rência ao próximo elemento, do elemento do fim da LISTA (ultimo elemento), em vez de ficar com NULL para identificar o fim (descontinuidade), receba a referência do primeiro elemento da LISTA, tornando-a circular.

Isso pode ser feito utilizando herança na classe LISTA, especializando uma Classe LISTA CIRCULAR, conforme modelo apresentado na Figura 3. Esta clas-se herdará de LISTA as suas características e reescreverá os métodos INSERE INICIO e REMOVE INICIO, porque em ambos os casos devemos atribuir a referência ao atributo próximo do último elemento, de modo que ele sempre faça referência ao primeiro elemento. Nos outros métodos de inserção e remo-ção, isso não é necessário, pois tudo já esta adequado.

Page 11: Implementacao LISTA Em JAVA

Figura 3 – Diagrama de Classe da LISTA com a LISTA CIRCULAR.

public class ListaCircular extends Lista{

public void insereInicio(Object dado){

//insere primeiro item

ItemLista novoItem = new ItemLista();

ItemLista aux = this.primeiro;

novoItem.atribuiDado(dado);

if (this.numeroElementos == 0)

novoItem.atribuiProx(novoItem); // referencia circular!!!

else {

novoItem.atribuiProx(this.primeiro);

for(int i=1; i<this.numeroElementos; i++) //encontra o ultimo item

aux=aux.retornaProx();

aux.atribuiProx(novoItem); //prox do ultimo referencia o primeiro item

}

this.primeiro = novoItem;

this.numeroElementos ++;

}

// Remove primeiro item

public void removeInicio(){

if (! vazia()){

ItemLista ItemRemovido = this.primeiro ;

if (this.numeroElementos == 1)

this.primeiro = null;

else {

ItemLista aux = this.primeiro;

this.primeiro = this.primeiro.retornaProx();

for(int i=1; i<this.numeroElementos; i++)//encontra o ultimo item

aux=aux.retornaProx();

aux.atribuiProx(this.primeiro);//prox do ultimo referencia 1º item

}

AULA 3 • ESTRUTURA DE DADOS

UNIVALI/UNITINS • SUPERIOR DE TECNOLOGIA • 3º PERÍODO 45

Também criamos um novo método denominado DESLOCA, que tem a função de fazer com que a LISTA (referência ao início da lista) seja deslocada, permitindo que se faça o processo de contagem, eliminação e reinício da contagem dos soldados. A seguir, apresentamos a Classe LISTACIRCULAR. Ve-rifique com calma para entender os detalhes de como ela foi implementada.

Page 12: Implementacao LISTA Em JAVA

this.numeroElementos --;

ItemRemovido = null;

}

}

//desloca referencia do primeiro da lista para o proximo elemento da lista

public void desloca(){

this.primeiro = this.primeiro.retornaProx();

}

}

public class Main {

public Main() {

}

public static void main(String[] args) {

ListaCircular soldados = new ListaCircular();

// Prepara a lista.

soldados.insereInicio(“A”);

soldados.insereFim(“B”);

soldados.insereFim(“C”);

soldados.insereFim(“D”);

soldados.insereFim(“E”);

soldados.insereFim(“F”);

soldados.insereFim(“G”);

soldados.Mostra();

// sorteia um numero para a contagem

int numeroContagem = (int)(Math.random()*10)+1;

numeroContagem = 4;

System.out.println(“Numero para contagem: “+numeroContagem);

// sorteia o soldado que vai começar a contagem

int soldadoInicial = (int)(Math.random()*soldados.quantElementos());

soldadoInicial = 7;

System.out.println(“Soldado inicial: “+soldadoInicial);

// rotina para posicionar a referencia da lista no soldado inicial

for (int i = 1; i < soldadoInicial; i++)

soldados.desloca();

// rotina para determinar o soldado que saira com o cavalo

while(soldados.quantElementos() > 1){

for (int i = 1; i < numeroContagem; i++)

soldados.desloca();

System.out.println(“Soldado retirado: “+soldados.dadoInicio());

soldados.removeInicio(); // remove o soldado

soldados.Mostra();

}

// o que sobrou é o que deve usar o cavalo.

System.out.println(“soldado que usará o cavalo: “ + soldados.dadoInicio());

}

}

46 3º PERÍODO • SUPERIOR DE TECNOLOGIA • UNIVALI/UNITINS

AULA 3 • ESTRUTURA DE DADOS

Essa solução simplificada não interage com o usuário para simplificar os testes. Os soldados são inseridos diretamente no código, sendo que o soldado de onde inicia a contagem e o valor para contagem são gerados de forma aleatória.

Page 13: Implementacao LISTA Em JAVA

AULA 3 • ESTRUTURA DE DADOS

UNIVALI/UNITINS • SUPERIOR DE TECNOLOGIA • 3º PERÍODO 47

Como você pôde observar, o processo de determinação do vencedor é sim-ples. A contagem é iniciada no soldado sorteado, e ao contar, a referência da LISTA é deslocada para o local do fim da contagem. Esse soldado (elemento da LISTA) é removido e a contagem reinicia no soldado seguinte. Como a LISTA é CIRCULAR, a contagem pode ser feita sequencialmente sem a preocupação com o fim da LISTA, pois ao chegar ao fim da LISTA, o deslocamento para o próximo elemento vai diretamente para o primeiro e tudo reinicia automaticamente.

Conclusão

Mais uma vez, fizemos a transformação do TAD para Classe, mas nesta aula com a estrutura de dados LISTA. Da mesma forma que foi feito com as estruturas de dados anteriores (Pilha e Fila), transformamos a definição do tipo LISTA em atributos da Classe e as operações (procedimentos e funções) em métodos dessa classe.

Com a implementação em Java da Classe LISTA foram elaborados dois exemplos: um para testar o funcionamento da LISTA e outro para resolver o pro-blema dos soldados. Com essas implementações, pode-se verificar como fica a integração da estrutura de dados com o resto do programa que a utiliza.

Aproveitando o problema dos soldados, foi feita uma especialização da Classe LISTA para uma LISTA CIRCULAR, que auxiliou a solucionar o problema de forma mais natural.

Síntese da aula

Nesta aula, estudamos a estrutura de dados LISTA, que tem como caracte-rística principal o fato de suas operações de inserção e remoção de dados po-derem ser feitas em qualquer lugar da LISTA. Para implementar essa estrutura de dados em JAVA, seguimos o mesmo caminho já trilhado nas aulas anteriores.

Foi feita a implementação da Classe LISTA com todos os métodos necessários. Um programa para testar o funcionamento da LISTA foi elaborado e apresentado.

Na seqüência, foi proposto um problema que pode ser resolvido utilizan-do LISTA, mas para resolver de forma mais natural, em função das característi-cas do problema (círculo), criamos uma especialização da Classe LISTA, para torná-la uma LISTA CIRCULAR. Foi apresentado o diagrama desta classe e a implementação em Java da Classe e da solução do problema dos soldados.