2. Listas encadeadas ou listas ligadas
representam uma seqüência de objetos na
memória do computador.
Exemplo: Lista de afazeres
1. Comprar uma lâmpada
2. Trocar uma lâmpada queimada
3. Procurar uma conta no quarto
4. Pagar uma conta na internet
5. Desligar o computador
6. Dormir
3. Na lista de afazeres anterior, uma tarefa
dependia da execução da tarefa anterior
Próxima
Ação atual ação
4. 1. Comprar 2
lâmpada
2. Trocar 3
lâmpada
3. Procurar 4
conta
4. Pagar 5
conta
5. Desligar 6
micro
6. Dormir fim
5. Como representar a lista anterior em um
programa escrito na Linguagem C?
◦ Primeira opção: vetores ou matrizes
Tarefa: Comprar Trocar Procurar Pagar Desligar
Dormir
lâmpada lâmpada conta conta micro
Índice: 1 2 3 4 5 6
6. Primeira opção: vetores ou matrizes
◦ Como acrescentar “Ligar micro”?
Tarefa: Comprar Trocar Procurar Pagar
Ligar Desligar
Dormir
lâmpada lâmpada conta conta
micro micro
Índice: 1 2 3 4 5 6 7
7. Primeira opção: vetores ou matrizes
◦ Os itens da lista são armazenados em posições
contíguas de memória.
◦ A lista pode ser percorrida em qualquer direção.
◦ A inserção de um novo item pode ser realizada
após o último item com custo constante.
◦ A inserção de um novo item no meio da lista requer
um deslocamento de todos os itens localizados
após o ponto de inserção.
◦ Retirar um item do início da lista requer um
deslocamento de itens para preencher o espaço
deixado vazio.
8. Segunda opção: ponteiros
◦ Estruturas de dados dinâmicas: estruturas de dados
que contém ponteiros para si próprias.
struct lista {
char nome_tarefa[30];
float duracao;
char responsavel[30];
...
ponteiro para a
struct lista *prox;
própria estrutura lista
};
9. Representação gráfica de um elemento da lista:
campos de informação
próximo nó
◦ Cada item é encadeado com o seguinte, mediante uma
variável do tipo ponteiro.
◦ Permite utilizar posições não contíguas de memória.
◦ É possível inserir e retirar elementos sem necessidade de
deslocar os itens seguintes da lista.
10. Cada item em particular de uma lista pode ser
chamado de elemento, nó, célula, ou item.
O apontador para o início da lista também é
tratado como se fosse uma célula (cabeça), para
simplificar as operações sobre a lista.
O símbolo / representa o ponteiro nulo (NULL),
indicando o fim da lista.
p
3
5
2
4 /
11. Podemos realizar algumas operações sobre
uma lista encadeadas, tais como:
◦ Inserir itens;
◦ Retirar itens;
◦ Buscar itens.
Para manter a lista ordenada, após realizar
alguma dessas operações, será necessário
apenas movimentar alguns ponteiros (de um
a três elementos).
12. Outras operações possíveis:
◦ Criar uma lista
◦ Destruir uma lista
◦ Ordenar uma lista
◦ Intercalar duas listas
◦ Concatenar duas listas
◦ Dividir uma lista em duas
◦ Copiar uma lista em outra
14. Podemos inserir itens:
◦ No início de uma lista
◦ No final de uma lista
◦ No meio de uma lista
15. O endereço armazenado no ponteiro p deve
ser alterado para o endereço do item a ser
acrescido à lista.
p 5 2 4 /
3
16. No* insere (No* l, float v)
{
No* p = (No*) malloc(sizeof(No));
p->info = v;
p->proximo = l;
return p;
}
Prof. Adriano Teixeira de Souza
17. O endereço armazenado em p será alterado
caso a lista esteja vazia ou
O campo prox do último item será alterado.
/
p 3 /
p 3 5 /
18. Campo prox do item a ser inserido recebe o
campo prox do item posterior
Campo prox do item antecessor recebe o
endereço do item a ser inserido
p 3 2 4 /
5
lista[5].prox ← lista[2]
lista[3].prox ← 5
19. O endereço armazenado no ponteiro p deve
ser alterado para o endereço do item que
segue o primeiro item da lista.
p 5 2 4 /
20. O campo prox do último item será alterado
caso a lista contenha mais de um item ou
O endereço armazenado em p será alterado
para NULL.
p 3 5 /
p 3 /
/
21. Item antecessor recebe o campo prox do
item a ser removido
lista[3].prox ← lista[5].prox
p 3 5 2 4 /
22. No* retira (No* l, float v) {//Em qualquer posicao
No* ant = NULL;
No* p = l;
while (p != NULL && p->info != v) {
ant = p;
p = p->proximo;
}
if (p == NULL)
return l;
if (ant == NULL) {
l = p->proximo;
}else {
ant->proximo = p->proximo;
}
free(p);
return l;
}
23. No* busca (No* l,float v){
No* q;
int i=0;
for (q=l; q!=NULL; q=q->proximo){
if(q->info == v){
printf("nnachou %dnnn",i);
return q;
}
i++;
}
return NULL;
}
Prof. Adriano Teixeira de Souza
24. void imprime (No* l){
No* q;
for (q=l; q!=NULL; q=q->proximo)
printf("%fn", q->info);
}
Prof. Adriano Teixeira de Souza
25. void libera (No* l) {
No* q = l;
while (q!=NULL) {
No* t = q->proximo;
free(q);
q = t;
}
}
Prof. Adriano Teixeira de Souza
26. main(){
No* p = cria();
p = insere (p,20.0);
p = insere (p,44.5);
p = insere (p,33.3);
p = insere (p,20.9);
imprime (p);
No* n = busca(p,20.3);//Busca
if (n != NULL){
printf ("Encontrado: %fn", n->info);
p=retira(p,n->info);
}
printf ("Configuracao da fila:n");
imprime (p);
libera (p);
system("pause");
}
Prof. Adriano Teixeira de Souza
27. No* insere_ordenado (No* l, float v)
{
No* novo = (No*) malloc(sizeof(No));
novo->info = v;
No* ant = NULL;
No* p = l;
while (p != NULL && p->info < v) {
ant = p;
p = p->proximo;
}
if (ant == NULL) {
novo->proximo = l;
l = novo;
} else {
novo->proximo = ant->proximo;
ant->proximo = novo;
}
return l;
}
Prof. Adriano Teixeira de Souza