Professora Jeane Melo
Roteiro Lista Encadeada Alocação: Estática x Dinâmica O que são Ponteiros?
Ponteiros Variáveis que Armazenam Endereços de Memória Mas, toda variável não é armazenada na memória?
Ponteiros Toda variável é armazenada na memória. Mas, os ponteiros armazenam variáveis que armazenam o endereço de memória. Variáveis são armazenadas na memória(gavetas) As gavetas possuem uma localização, endereço. Ponteiros apontam para o ENDEREÇO da Memória (Ponteiros sabem em que gaveta está a variável)
Ponteiros Variável Comum O conteúdo é um valor (instâncias de um determinado tipo) Ao atribuirmos um valor modificamos apenas o conteúdo da variável atual Ponteiros Referência: indica um endereço na memória Ao modificarmos o valor armazenado naquela referência alteramos os valores das variáveis que apontam para ela.
Ponteiros Em C/C++ Por default, as variáveis armazenam valores Criar ponteiros explicitamente Em Java Tipos primitivos armazenam valores Tipos compostos (classes) armazenam referências
Alocação Estática Quantidade Memória Prédefinida. Conteúdo armazenados em endereços estáticos. Exemplo: var num: integer; Num := 5;
Alocação Dinâmica Alocação de memória feita em tempo de execução Qual a relação de Alocação Dinâmica de memória e Ponteiros?
Alocação Dinâmica Ponteiros sabem em que gaveta está a variável. O comando malloc escolhe em que gaveta será guardada a variável que armazena o ENDEREÇO de memória.
Endereços e Ponteiros Variáveis Endereços (fictícios) char c; int i; struct { int x, y; } ponto; int v[4]; c 89421 i 89422 ponto 89426 v[0] 89434 v[1] 89438 v[2] 89442 v[3] 89446 Se i é uma variável &i é seu endereço
Endereços e Ponteiros Ponteiro Tipo especial de variável que armazena endereços NULL Se p armazena o endereço de i, então *p é o valor do objeto apontado por p (*p=i) Para declarar um ponteiro para um inteiro em C usamos: int *p
Endereços e Ponteiros Para usarmos as funções relacionadas com alocação dinâmica em C (malloc e free), precisamos incluir a biblioteca stdlib no início do programa: #include <stdlib.h> A função malloc (abreviatura de memory allocation) aloca um bloco de bytes consecutivos na memória do computador e devolve o endereço desse bloco A função free libera a porção de memória alocada por malloc
Alocação Dinâmica A memória é alocada no momento em que é requisitada. C e Java possuem comandos para alocação de memória ( criar as caixinhas ) Java: Ponto p = new Ponto(800,600); C: struct Ponto *p; p = (struct Ponto *) malloc(sizeof(struct Ponto));
Alocação Dinâmica Em C, precisamos liberar o espaço alocado para uma variável antes de eliminar uma referência para esta. Para isto utilizamos o comando free : free(p) Em Java, não é necessário tal operação, esta é realizada a cada garbage collection
Alocação Estática X Dinâmica Estática A quantidade de memória é definida previamente e não muda durante a execução do programa. Alocação consecutiva Acesso direto Não permite a adição de elementos durante a execução (dinamicamente)
Alocação Estática X Dinâmica Dinâmica A quantidade de memória utilizada pelo programa pode variar durante a execução do mesmo. Cada elemento é representado separadamente Os elementos são conectados através de ponteiros Flexibilidade Mais espaço Não é possível acessar um elemento diretamente
Alocação Estática X Dinâmica Acesso direto Estática Inserção e remoção no final da lista Inserção e remoção no meio da lista Dinâmica O acesso não é direto Inserção e remoção de elementos Memória adicional para armazenar os ponteiros
Lista Encadeada Listas Posição relativa dos elementos Os elementos são dispostos linearmente a 1 a 2 a 3... a n a 1 - primeiro elemento a n - último elemento O elemento a i, é precedido do elemento a i-1 e seguido do elemento a i+1
Lista Encadeada Operações comuns Busca Inserção Remoção Substituição Outras operações Ordenação, União, Particionamento, Determinação do total de elementos.
Lista Encadeada Listas Arrays Encadeamento Pilhas, Filas Listas Encadeadas
Lista Encadeada Lista Exemplo mais simples de alocação dinâmica Lista de pares (armazenam uma quantidade variável de elementos do mesmo tipo) Cada par é representado por um registro que consiste de um elemento e de um endereço Normalmente contém uma referência para o 1 o nó da lista Lista elemento prox NULL elemento prox elemento prox elemento prox NULL
Lista Encadeada Usando OO (java) A lista é composta por células (ou nós) Cada célula (ou nó) possui um Objeto (info) e um apontador(next) para um o próximo elemento da lista class Node { int valor; Node next; }
Lista Encadeada O último nó da lista não aponta para lugar nenhum (null). public Node (int valor) { this.valor = valor; this.next = null; }
Lista Encadeada Classe Lista class Lista { Node inicio; public Lista() { this.inicio = null; } //Acrescentamos as operações associadas public void inserir(int valor) {...} }
Lista Encadeada Criar uma classe Nó (ou Node) com dois atributos: um para guardar um objeto(info) e outro para guardar uma referência ao próximo nó da lista. Criar uma classe que represente uma lista encadeada Nesta classe teremos um nó que representa o início da lista (denominado cabeça) Para as operações de inserção, verificamos se a lista está vazia.
Lista Encadeada sequência de células cada célula contém um objeto de algum tipo e o endereço da célula seguinte Supondo que os objetos são do tipo int (Em C: ) struct cel { }; int conteudo; struct cel *prox; Conteudo Prox typedef struct cel celula; //tratar como um novo tipo de dados
Lista Encadeada celula c; // declaração de uma célula celula *p; // declaração de um ponteiro para célula c.conteudo //conteúdo da célula c.prox // endereço da próxima célula p->conteudo // conteudo da celula p->prox //endereço da próxima celula
Lista Encadeada // criando uma lista celula *ini; ini = malloc (sizeof (celula)); ini->prox = NULL; //imprimindo uma lista void imprima (celula *ini) { celula *p; for (p = ini->prox; p!= NULL; p = p->prox) printf ("%d\n", p->conteudo); }
Lista Encadeada void insere (int x, celula *p) { celula *nova; nova = malloc (sizeof (celula)); nova->conteudo = x; nova->prox = p->prox; p->prox = nova; }
Lista Encadeada p Insere Após inserção elto1 prox elto2 prox X prox NULL p X prox elto1 prox elto2 prox NULL
Lista Encadeada //buscar um elemento x em uma lista encadeada celula *busca (int x, celula *ini) { celula *p; p = ini->prox; while (p!= NULL && p->conteudo!= x) p = p->prox; return p; }
Lista Encadeada void remove (celula *p) { celula *morta; morta = p->prox; p->prox = morta->prox; free (morta); }
Lista Encadeada void buscaeremove (int y, celula *ini) { celula *p, *q; p = ini; q = ini->prox; while (q!= NULL && q->conteudo!= y) { p = q; q = q->prox; } if (q!= NULL) { p->prox = q->prox; free (q); } }
Lista Encadeada P elemento prox elemento prox elemento prox NULL P MORTA elemento prox elemento prox elemento prox NULL
Lista Encadeada Outros tipos de Lista Circular Duplamente encadeada
Lista Circular Lista elemento prox elemento prox elemento prox Lista NULL elemento prox elemento prox elemento prox
Lista Duplamente Encadeada Cada celula passa a ter três campos: elemento o conteúdo propriamente dito prox endereço da próxima célula ant endereço da célula anterior
Lista Duplamente Encadeada Lista ant elemento prox ant elemento prox ant elemento prox NULL
Exercício Implemente a lista encadeada em Java ou C Faça uma apresentação (ppt) sobre a sua implementação Entrega: Sexta-feira 13/05 (impresso Código + apresentação)
Referências Capítulo 10 - Cormen Lista encadeada (Paulo Feofiloff - IME-USP) http://www.ime.usp.br/~pf/algoritmos/aulas/lista.html