Listas Encadeadas.

Slides:



Advertisements
Apresentações semelhantes
TADs Vector, Lista e Sequência
Advertisements

ADT – Arvore Binária de Pesquisa
While While Condição // comandos End While. Exemplos While Var contador As Integer contador = 0 While (contador < 10) contador += 1 console.ConsoleWrite(contador)
Estruturas Fundamentais
Listas Encadeadas Circulares Listas Duplamente Encadeadas
Listas Encadeadas Circulares Listas Duplamente Encadeadas
Espalhamento.
2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti.
Prof. José Fernando Rodrigues Júnior Pacotes Material original: Profa. Elaine Parros Machado de Sousa SCC Bancos de Dados e Suas Aplicações.
Procedimentos e Funções
Banco de Dados Aula 01: Conceitos Básicos
GRAFOS. Motivação Muitas aplicações em computação necessitam considerar conjunto de conexões entre pares de objetos: –Existe um caminho para ir de um.
SISTEMA BINÁRIO Hardware de Computadores. SISTEMA BINÁRIO Hardware de Computadores.
PROGRESSÃO ARITMÉTICA P.A.
Prof. Celso Gramática.
FORTRAN 90 Denise Yumi Takamura.
Estruturas de Dados para projeto de SGBD. Estruturas de dados analisadas Estruturas de nível Esparso Denso Combinadas Arvore B+ Tabela de hash.
SQL-3. Novo contexto e necessidade de : Manipular imagens Outros tipos de dados além de texto e números Recuperação de dados mais complexos Níveis distintos.
Vetores (2) Continuação.
Criptografia Quântica : Um Estudo
(Como implementar multiplicação e divisão uma vez só :-)
Gustavo Vieira Pereira
Algoritmos Genéticos - Capítulo 10 Desvantagens da Representação Binária Prof. Ricardo Linden.
Profa. Graziela Santos de Araújo Algoritmos e Programação II, 2010
Introdução A fim de preparar a geração de código, deve-se relacionar o fonte estático do programa às ações em tempo de execução. Durante a execução, o.
Problema do percurso mínimo
Planejando seu site Objetivos Abordagem Sílvia Dota.
Agregado Homogêneo e Heterogêneo
CES-11 LAB 03 Bitmap Quadtree
Capítulo VII – Tipos Enumerativos e Estruturas 7.1 – Tipos enumerativos 7.2 – A necessidade de estruturas 7.3 – Manipulação dos campos de uma estrutura.
CES-10 INTRODUÇÃO À COMPUTAÇÃO Aulas Práticas – 2013 Capítulo VII Variáveis Indexadas Numéricas.
CES-10 INTRODUÇÃO À COMPUTAÇÃO Capítulo XI Noções de Estruturas de Dados.
CES-10 INTRODUÇÃO À COMPUTAÇÃO Aulas Práticas – 2013 Capítulo XI Encadeamento de Estruturas por Ponteiros.
Capítulo IX – Ponteiros 9.1 – Introdução 9.2 – Relação entre ponteiros e variáveis indexadas 9.3 – Alocação dinâmica de memória 9.4 – Variáveis indexadas,
Exemplo: ordenação de uma lista pelo Selection-Sort:
1 Definição de Dicionário Dicionário é um sistema de informações: Equivalente a um conjunto de elementos não repetidos Equivalente a um conjunto de elementos.
Capítulo I – Conceitos Primários 1.1 – Estrutura de um computador 1.2 – Informações manipuladas por um computador 1.3 – Evolução das linguagens de programação.
FUNDAÇÃO CARLOS CHAGAS
EEL170 COMPUTAÇÃO I Antonio Cláudio Gómez de Sousa 5a série de slides Versão 26/04/2012.
ALOCAÇÃO DINÂMICA DE MEMÓRIA
Teorema do Confronto Se não pudermos obter o limite diretamente, talvez possamos obtê-lo indiretamente com o teorema do confronto. O teorema se refere.
Interpolação Introdução Conceito de Interpolação
Aritmética de ponto flutuante Erros
Resolução de Sistemas Não-Lineares- Parte 1
Sistemas Lineares Parte 2
Organização de Sistemas de Computadores
Desempenho A rápida taxa de melhoria na tecnologia de computadores veio em decorrência de dois fatores: avanços na tecnologia utilizada na construção.
Listas Lineares.
Classificação Interna de Dados Estrutura de Dados I Prof. Mai-Ly Vanessa Campus Prof. Alberto Carvalho - UFS.
Caminhamentos e Construção
Tecnologia para Web JavaScript Enrique Pimentel Leite de Oliveira
Recursividade Estrutura de Dados.
Comandos básicos do MS-DOS
Marco Antonio Montebello Júnior
Curso em CD-ROM Técnicas de Vendas SLIDES MODELO ALEATÓRIOS.
Entendendo as definições de classe
Frações Professor: Graciano Pianezzer Beletti.
Curso de Programação em C++
Baseado no documento do Prof. Ronaldo Martins da Costa
LINGUAGENS DE PROGRAMAÇÃO
04:27 Introdução Tipos de Fluxo de Dados e de Arquivos Manipulação de Arquivos em Java Classes FileReader e FileWriter Classes FileInputStream e FileOutputStream.
Sistemas de Informação Prof. Me. Everton C. Tetila Modelo de dados relacional Banco de Dados I.
Programação Concorrente com Thread Java
Introdução Ciência da Computação estudo de algoritmos –ÊNFASE ao estudo de DADOS armazenamento manipulação refinamento (a partir de dados cru) estrutura.
1 Seja o resultado de um experimento aleatório. Suponha que uma forma de onda é associada a cada resultado.A coleção de tais formas de ondas formam um.
8. Uma Função de duas Variáveis Aleatórias
INPE / CAP-315 Airam J. Preto, Celso L. Mendes Aula 30 (1) Empacotamento de Dados em MPI Tópicos: Buffer de Mensagem Empacotamento/Desempacotamento.
Java Generics Adeline de Sousa Silva.
ArrayList e Genéricos Profs. PROG2 - UNISINOS.
Tipos Especiais de Listas
Transcrição da apresentação:

Listas Encadeadas

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.

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.

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

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

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!”);

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.

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.

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.

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.

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.

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.

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.

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

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);

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;

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;

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:

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);

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

Lista Duplamente Encadeada

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; }

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

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:

Multilista

Multilista

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 -2.147.483.648 a 2.147.483.647. 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.

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.

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