A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Listas Encadeadas.

Apresentações semelhantes


Apresentação em tema: "Listas Encadeadas."— Transcrição da apresentação:

1 Listas Encadeadas

2 Vantagens de listas encadeadas X arrays:
Lista encadeada: É uma coleção linear de objetos auto-referenciados de classe, chamados nós, conectados por links de referência. Em geral um programa acessa uma lista via uma referência ao primeiro item da lista. O programa acessa cada link subseqüente via a referência de link armazenada no nó anterior. A referência do último nó é marcada como null (terra) para marcar o fim da lista. Dados são armazenados em uma lista encadeada dinamicamente, o programa cria cada nó conforme o necessário. Um nó pode conter dados de qualquer tipo, inclusive uma referência a objetos de outra classe. Vantagens de listas encadeadas X arrays: - Listas encadeadas são dinâmicas, portanto seu tamanho pode aumentar ou diminuir conforme o necessário. - Lista encadeadas podem ser mantidas em ordem de classificação simplesmente inserindo cada elemento no ponto adequado da lista (a demora vai ser achar este ponto) não precisa mover os outros elementos da lista, (apenas duas referências são mudadas). - Nós de lista encadeada não estão armazenados contiguamente na memória, são apenas logicamente contíguos.

3 Listas simplesmente encadeadas: Uma lista é denominada simplesmente encadeada se em cada nó só existe um ponteiro que aponta para o próximo nó, cuja representação é feita da seguinte maneira: Em listas simplesmente encadeadas trabalhamos com alocação dinâmica de memória que já é a forma natural do Java trabalhar. O limite da alocação dinâmica de memória é igual ao espaço disponível em memória física + o disponível em mem. virtual (normalmente menor que isto pois estas memórias são compartilhadas por diversos aplicativos). É interessante lembrarmos que em Java não precisamos liberar explicitamente a memória alocada uma vez que ele próprio já faz a coleta automática de lixo.

4 Vejamos as operações mais básicas em uma lista encadeada:
Lista com um elemento: Inserir um nó na frente da lista:

5 Inserir nó no final da lista
Remover nó da frente da lista Inserir nó após determinado nó passado como parâmetro Remover nó após determinado nó passado como parâmetro Inserir no fim da lista

6 Continuando lista encadeada iremos agora procurar determinado elemento na lista:
Dado uma chave faça um método que retorne um ponteiro para o nó que contém o elemento procurado. Uma vez que estamos usando Strings como elementos devemos ver algumas características da classe String. Comparar o conteúdo de dois Strings com == não vai funcionar; Para verificar se o conteúdo de dois Strings é o mesmo usa-se o método equals de String. Ex: String nome, nome2; ... If (nome.equals(nome2)) System.out.println(“São iguais!”) else System.out.println(“São diferentes!”);

7 Agora que já vimos um pouco sobre comparações de Strings faça o método:
Dado uma chave faça um método que retorne um ponteiro para o nó que contém o elemento procurado.

8 Para verificar qual de dois Strings é o maior usa-se compareTo. Ex:
String nome, nome2; ... if (nome.compareTo(nome2) > 0) System.out.println(nome+” é maior que “+nome2); else if (nome.compareTo(nome2) < 0) System.out.println(nome+” é menor que “+nome2); else System.out.println(“São iguais”); compareTo retorna 0 se as Strings forem iguais < 0 se a string que invoca for menor que a passada como arg. > 0 se a string que invoca for maior que a passada como arg.

9 Agora que já vimos um pouco sobre comparações de Strings faça o método:
Faça um método que dada uma chave insira um nó na lista de forma ordenada. Procurar local onde vai inserir Guardar nó anterior ao ponto da inserção Inserir após o anterior que foi guardado (insereAposAtual) Verificar se o nó inserido não seria o primeiro da lista (neste caso vai ser chamado insereNaFrente) Dado uma chave faça um método que remova o nó que contém o elemento procurado.

10 Análise dos algoritmos:
A inserção e a remoção no início da lista encadeada é muito rápido uma vez que o número de operações é fixo e independe do tamanho da lista, sendo a ordem O(1). A busca, remoção e a inserção após um item específico precisam percorrer, em média, até a metade da lista, sendo a ordem O(N). Nas listas seqüenciais essas operações também têm ordem O(N), mas nas listas encadeadas a inclusão e a remoção são bem mais rápidas uma vez que não será necessário mover os itens para abrir vaga para inserir um item ou para ocupar a vaga do item removido.

11 Listas com nó cabeça Algumas implementações de listas encadeadas costumam manter um nó cabeça. A informação contida neste nó não representa nenhum ítem da lista, ele pode ser usado para conter informações gerais da lista como o número de nós e etc.

12 Exercício Com base no programa anteriormente feito crie uma classe que seja uma lista com nó cabeça, onde na cabeça seja registrada a quantidade de nós que estão na lista a cada momento. Crie um método ou classe que demonstre a utilização desta lista. Obs: A cabeça não entra na contagem da quantidade de nós. O nó firstNode agora vai estar dentro do nó cabeça.

13 Lista Circular Em uma lista circular o último nó da lista aponta para o primeiro. Nesta lista não se guarda o endereço do primeiro e do último nó da lista, guarda-se o endereço de somente um deles. Neste tipo de lista é possível acessar qualquer nó a partir de qualquer ponto, pois na verdade poderíamos considerar qualquer nó como sendo o primeiro. Na implementação deste tipo de lista é interessante que o ponteiro para a lista aponte para o nó final, e não para o primeiro, pois a partir do nó final poderemos acessar facilmente o primeiro nó da lista. As operações em uma lista circular são semelhantes as operações em uma lista comum, devemos apenas ter cuidado nas operações que envolvem o nó inicial e o nó terminal.

14 Lista Circular Vejamos como seria inserir um nó no início da lista:

15 Lista Circular Código para inserção de nó á frente de lista circular:
public void insereNaFrente(String n) { if (estaVazia()) listaNode = new Node(n); listaNode.proxNode = listaNode; } else listaNode.proxNode = new Node(n,listaNode.proxNode);

16 Lista Circular Código para remoção de nó da frente da lista circular
public Object removeDaFrente() { if (estaVazia()) System.out.println("Lista "+nomeLista+" se encontra vazia"); return null; } Object removido = listaNode.proxNode.data; if (listaNode == listaNode.proxNode) listaNode = null; else listaNode.proxNode = listaNode.proxNode.proxNode; return removido;

17 Lista Circular Código para inserção de nó ao final da lista circular
public void insereNoFim(String n) { if (estaVazia()) listaNode = new Node(n); listaNode.proxNode = listaNode; } else listaNode.proxNode = new Node(n,listaNode.proxNode); listaNode = listaNode.proxNode;

18 Lista Duplamente Encadeada
Para uma maior flexibilidade na manipulação de listas lineares, podemos incluir dois ponteiros em cada nó, um para apontar para o próximo nó e o outro para apontar para o nó anterior, como mostrado na seguinte figura:

19 Lista Duplamente Encadeada
A classe nó para uma lista duplamente encadeada seria: class Node { Object dado; Node proxNode; Node ant; //Construtor principal, cria um nó e o liga a um anterior e um próximo Node(Object d, Node anterior, Node proximo) dado = d; ant = anterior; proxNode = proximo; } //Construtor para um último nó, na verdade chama o de três Node(Object d) this(n,null,null);

20 Lista Duplamente Encadeada
Como adicionamos mais um ponteiro no nó, uma lista duplamente encadeada ocupa mais espaço que uma lista simplesmente encadeada. No entanto, a vantagem que temos em poder percorrer a lista nas duas direções compensa a memória extra que utilizamos. Além disso, agora podemos excluir qualquer nó conhecendo apenas o ponteiro que aponta para ele. Vejamos como seriam algumas rotinas em lista duplamente encadeada: Inserir nó no início da lista

21 Lista Duplamente Encadeada

22 Lista Duplamente Encadeada
Rotina que insere um nó após o nó corrente. public void insereAposAtual(Node atual,Object n) { if (estaVazia()) primNode = ultiNode = new Node(n); else atual.proxNode = new Node(n,atual,atual.proxNode); if (atual == ultiNode) ultiNode = ultiNode.proxNode; atual.proxNode.proxNode.ant = atual.proxNode; }

23 Lista Duplamente Encadeada
Rotina que remove o primeiro nó da lista. Rotina que remove o nó corrente.

24 Multilista Uma estrutura na qual um nó aparece em mais de uma lista e contém mais de um ponteiro é denominada de lista multiencadeada ou multilista. Uma lista duplamente encadeada é um exemplo de multilista. Como outro exemplo de multilista, suponha que desejamos armazenar a relação de disciplinas oferecidas por uma escola e, para cada disciplina, desejamos armazenar os alunos que estão matriculados. Para as disciplinas iremos armazenar o código e o nome da disciplina e para os alunos iremos armazenar o número de matrícula e o seu nome. A seguinte figura representa a estrutura que nós queremos:

25 Multilista

26 Multilista

27 Abrindo aspas – Números aleatórios
Para introduzir o elemento sorte em nossos programas podemos usar um gerador de números aleatórios fornecido, em Java, pela classe Random do pacote java.util. Esta classe pode gerar valores aleatórios dos tipos, int, double, boolean, byte e float. Um novo objeto gerador de números aleatórios pode ser criado como a seguir: Random numAleatorio = new Random( ); Podemos então gerar um inteiro aleatório da seguinte forma: int num = numAleatorio.nextInt( ); A chamada acima gera valores aleatórios no intervalo de a Se quisermos determinar uma faixa de valores podemos usar passar um inteiro para uma segunda versão de nextInt onde ele irá retornar um número que pode ir de 0 até o argumento -1.

28 Exercício – Entrega próxima aula (pode ser em dupla)
Considere o seguinte problema que pode ser resolvido de uma forma bastante elegante usando uma lista circular. Esse problema é conhecido como problema de Josephus. A seguir apresentamos uma versão do problema. Um agente de viagem selecionou n clientes para participar de uma competição para ver que ganharia um cruzeiro em volta do mundo. O agente colocou os clientes em um círculo e sorteou um número m, sendo m <= n. Começando com o nome de um dos participantes, o agente conta no sentido horário em torno do círculo. Quando a contagem atingir o número m, o participante é removido do círculo e a contagem recomeça a partir do próximo participante. O último participante que for removido ganhará a competição. Faça um programa em Java que usando uma lista circular implemente o problema de Josephus. Leia os nomes dos participantes do cruzeiro e vá realizando os sorteios a cada sorteio o nome do eliminado deve ser mostrado bem como os participantes que continuam concorrendo.

29 Trabalho (em dupla) Gerenciamento de histórico de aluno usando multilista Cada aluno aponta para o próximo aluno Aluno tem nome e matrícula Cada aluno aponta para uma lista de disciplinas que já cursou Cada disciplina tem nota, presença, situação, ano e período cursado Situação pode ser: AP, RM, RF, TR Entrega: 30/11/2010


Carregar ppt "Listas Encadeadas."

Apresentações semelhantes


Anúncios Google