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
Ponteiros
O conteúdo é um valor
(instâncias de um determinado
tipo)
Ao atribuirmos um valor
modificamos apenas o
conteúdo da variável atual
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
Qual a relação de
Alocação Dinâmica de
execução
memória e Ponteiros?
Alocação Dinâmica
Ponteiros “sabem” em que
gaveta está a variável.
malloc
O comando
“escolhe” em que gaveta será
guardada a variável que
armazena o ENDEREÇO de
memória.
Endereços e Ponteiros
Variáveis
char c;
int i;
struct {
int x, y;
} ponto;
int v[4];
Endereços (fictícios)
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
Estática
Acesso direto
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
a1 a2 a3 ... an
a1 - primeiro elemento
an - último elemento
O elemento ai , é precedido do elemento ai-1 e seguido
do elemento ai+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
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 1o nó da
lista
Lista
Lista
elemento
prox
elemento
prox
elemento
NULL
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
Insere
p
elto1
prox
elto2
Após inserção
prox
NULL
X
p
prox
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
NULL
Lista
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