Listas Ligadas (Encadeadas) Listas Simplesmente Encadeadas

Documentos relacionados
A regra de acesso aos dados de uma fila é a seguinte: O primeiro elemento que entra (na fila) é o primeiro que sai (FIFO first in, first out).

INF1007: Programação 2 8 Listas Encadeadas. (c) Dept. Informática - PUC-Rio 1

Estrutura de Dados. Ricardo José Cabeça de Souza Parte 9

Computadores Digitais 2. Prof. Rodrigo de Souza Couto

Módulo 10 Listas Encadeadas

Listas ligadas/listas encadeadas

LISTAS ENCADEADAS OU NÃO- SEQÜENCIAIS. Estrutura de Dados

Instituto de C. Linguagem C: Listas. Luis Martí Instituto de Computação Universidade Federal Fluminense -

Programação II. Listas Encadeadas (Linked Lists) Bruno Feijó Dept. de Informática, PUC-Rio

Introdução a Programação. Listas Encadeadas

Estruturas de Dados. Módulo 17 - Busca. 2/6/2005 (c) Dept. Informática - PUC-Rio 1

Estruturas de Dados Aula 12: Outras Implementações de Listas 18/04/2011

Aula 14 Listas Duplamente Encadeadas. prof Leticia Winkler

Atividade de laboratório listas encadeadas simples

Listas Encadeadas. David Menotti Algoritmos e Estruturas de Dados II DInf UFPR

Linguagem C: Listas Encadeadas

Listas Lineares. Livro Projeto de Algoritmos Nívio Ziviani Capítulo 3 Seção 3.1

ÁRVORE BINÁRIA DE BUSCA

12. Filas Interface do tipo fila

Lista com descritor (continuação)

REVISÃO DE PILHAS E FILAS. Vanessa Braganholo Estruturas de Dados e Seus Algoritmos

Algoritmos e Estruturas de dados

Listas Lineares. continuando...

1. Listas sequenciais versus listas ligadas. Lista sequencial

Matrizes Esparsas. Prof. Fernando V. Paulovich *Baseado no material do Prof. Gustavo Batista

Métodos Computacionais. Variações de Listas Encadeadas

PONTEIROS E LISTAS. Kalinka Regina Lucas Jaquie Castelo Branco

Lista Encadeada (Linked List)

Alocação de Memória. Lucas Ferrari de Oliveira Professor Adjunto Universidade Federal do Paraná (UFPR)

Aula 17: Ponteiros e Alocação Dinâmica em C

Listas Estáticas. SCC Algoritmos e Estruturas de Dados I. Prof. Fernando V. Paulovich. *Baseado no material do Prof.

Filas. Prof. Túlio Toffolo BCC202 Aula 12 Algoritmos e Estruturas de Dados I

AULA 14 ESTRUTURA DE DADOS

Árvores Binária de Busca. Prof. César Melo DCC/ICE/UFAM

struct Nodo { int struct Nodo struct Nodo typedef struct Nodo *PNodo; int ConstruirLista (PNodo *H, PNodo *T) { int Criar

SCC 202 Prova 1. 28/9/2010 Resolução e Comentários

Ponteiros e Tabelas. K&R: Capítulo 5

Árvores. Prof. César Melo DCC/ICE/UFAM

Estruturas de Dados Filas

Aula 10 Alocação Dinâmica de Memória Listas Encadeadas. prof Leticia Winkler

Listas Lineares Ordenadas

Árvore Binária de Busca. Prof. César Melo

Estrutura de Dados. Carlos Eduardo Batista. Centro de Informática - UFPB

Estruturas de Dados Aula 10: Listas (parte 2) 19/04/2011

Programação: Vetores

Árvores. Prof. César Melo DCC/ICE/UFAM

Tipos abstratos de dados; pilhas e filas

1 Exercícios com ponteiros

REVISÃO DE C. Vanessa Braganholo Estruturas de Dados e Seus Algoritmos

Estruturas de Dados I

Árvores B. Prof. Márcio Bueno. / Fonte: Material da Prof a Ana Eliza Lopes Moura

DAS5102 Fundamentos da Estrutura da Informação

Pilhas e Filas Encadeadas. Algoritmos e Estruturas de Dados I

Pilhas e Filas. Livro Projeto de Algoritmos Nívio Ziviani Capítulo 3 Seção 3.2 e 3.3

LISTAS LINEARES. Estrutura de Dados

Transcrição:

Listas Ligadas (Encadeadas) Matrizes são estruturas de dados muito úteis fornecidas nas linguagens de programação. No entanto, elas têm pelo menos duas limitações: 1- Seu tamanho tem que ser conhecido no momento da compilação. 2- Os dados em uma matriz estão separados na memória do computador pela mesma distância, o que significa que inserir um item dentro da matriz exige que se movam outros dados nessa matriz. Tal limitação pode ser superada usando-se estruturas ligadas. Uma estrutura ligada é uma coleção de nós, que armazenam dados e ligações com outros nós. Desse modo, os nós podem estar em qualquer lugar na memória, e a passagem de um nó para outro da estrutura ligada é realizada armazenando os endereços de outros nós na estrutura ligada. Listas Simplesmente Encadeadas Uma lista simplesmente encadeada é uma sequência de nós, onde cada nó contém uma informação de algum tipo de dado e o endereço do nó seguinte. Vamos supor que a informação seja uma variável do tipo int. Veja abaixo um exemplo de uma lista simplesmente encadeada. Lista 1 2 3 Onde: lista é um ponteiro para o primeiro nó da lista que contém o valor "1" e um ponteiro para o próximo nó. Já o último nó da lista aponta para NULL, indicando fim da lista. A estrutura de cada nó de uma lista pode ser definida assim: typedef struct { int info; struct lista *proximo; lista; 1

Criação de Novos Elementos (nós) para a lista Antes de inserirmos um elemento na lista, precisamos criá-lo da seguinte maneira: lista *criarelemento(int info){ lista *no = (lista*) malloc(sizeof (lista)); if (no == NULL){ return NULL; no->info = info; no->proximo = NULL; return no; Inserção de Nós na Lista Após a criação do nó, devemos inseri-lo na lista. Temos três casos para inserção de elementos na lista: O nó é inserido no início da lista O nó é inserido no meio da lista O nó é inserido no fim da lista Quando o nó é inserido no início da lista deve-se fazer o campo "próximo" deste nó apontar para o primeiro elemento da lista, e em seguida fazer a lista apontar para este nó recém-criado. Segue abaixo um exemplo em linguagem C void inseririnicio(lista **listatotal, lista *elemento){ if(*listatotal == NULL){ *listatotal = elemento; elemento->proximo =(struct lista *) *listatotal; *listatotal = elemento; 2

Quando o nó é inserido no fim da lista, deve-se fazer o campo "próximo" do último nó da lista apontar para o elemento que se deseja inserir. Para tanto, devemos percorrer a lista até encontrar o último elemento. Lembrando que o último elemento sempre aponta para NULL. Abaixo temos um exemplo em linguagem C. void inserirfim(lista **listatotal, lista *elemento){ lista *elementoauxiliar; /* Percorre a lista ateh encontrar o ultimo elemento */ while (elementoauxiliar->proximo!= NULL){ elementoauxiliar = (lista *) elementoauxiliar->proximo; elementoauxiliar->proximo = (struct lista *) elemento; Quando o nó é inserido no meio da lista, deve-se informar a partir de qual nó o novo elemento será inserido. Ou seja, vamos utilizar o campo "info" para fazer uma pesquisa na lista, e após encontrá-lo, inserir o novo elemento. Abaixo temos um exemplo em linguagem C. void inserirmeio(lista **listatotal, lista *elemento, int info){ lista *elementoauxiliar; int encontrou=0; /* Percorre a lista ateh encontrar o no procurado */ while(encontrou == 0 && elementoauxiliar->proximo!= NULL){ /* Verifica se o no atual eh o no procurado */ if (elementoauxiliar->info == info){ /* O novo no sera inserido apos o no atual */ elemento->proximo = elementoauxiliar->proximo; elementoauxiliar->proximo=(struct lista *) elemento; encontrou = 1; elementoauxiliar=(lista *) elementoauxiliar->proximo; 3

Percorrendo a Lista Em situações de busca por um valor, ou para impressão de uma lista, deve-se percorrer a lista a partir do primeiro elemento até onde for desejado, ou seja, até achar o nó (elemento) procurado ou chegar ao final da lista. Veja abaixo um exemplo para encontrar o nó procurado. lista *buscarelemento(lista **listatotal, int valorprocurado){ lista *elementoauxiliar; int encontrou=0; /* Percorre a lista ateh encontrar o no procurado, ou ateh o fim da lista */ while(encontrou == 0 && elementoauxiliar!= NULL){ /* Verifica se o no atual contem o valorprocurado */ if (elementoauxiliar->info == valorprocurado){ /* encontrou o no procurado */ encontrou = 1; elementoauxiliar=(lista *)elementoauxiliar->proximo; /* Se encontrou o no procurado, retorna o no */ if (encontrou == 1){ return elementoauxiliar; /* Se nao encontrou, retorna NULL */ return NULL; 4

Remover um Elemento da Lista A função para retirar um elemento da lista é mais complexa. Se descobrirmos que o elemento a ser retirado é o primeiro da lista, devemos fazer com que o novo valor da lista passe a ser o ponteiro para o segundo elemento, e então podemos liberar o espaço alocado para o elemento que queremos retirar. Se o elemento a ser removido estiver no meio da lista, devemos fazer com que o elemento anterior a ele passe a apontar para o elemento seguinte, e então podemos liberar o elemento que queremos retirar. Devemos notar que, no segundo caso, precisamos do ponteiro para o elemento anterior para podermos acertar o encadeamento da lista. Veja abaixo as figuras que ilustram a remoção. Remoção do primeiro elemento (nó) da lista Remoção de um elemento (nó) no meio da lista Segue abaixo um exemplo em linguagem C de uma função para retirar um elemento (nó) da lista. Inicialmente, busca-se pelo elemento (nó) que se deseja retirar, guardando uma referência para o elemento anterior. 5

int removerelemento(lista **listatotal, int valorprocurado){ lista *elementoauxiliar, *elementoanterior; int encontrou=0; elementoanterior = *listatotal; /* Percorre a lista ateh encontrar o elemento (nó) procurado */ while (encontrou == 0 && elementoauxiliar!= NULL){ if (elementoauxiliar->info == valorprocurado){ /* Encontrou o elemento (nó) procurado */ encontrou = 1; /*nao encontrou o elemento(nó). Avança ao proximo */ elementoanterior = elementoauxiliar; elementoauxiliar=(lista *) elementoauxiliar->proximo; if (encontrou == 1){ /* Verifica se o elemento (nó) encontrado eh o primeiro da lista */ if (elementoanterior == elementoauxiliar && elementoauxiliar == *listatotal){ *listatotal = (lista *) elementoauxiliar->proximo; /*Caso o elemento(nó) encontrado nao seja o primeiro da lista*/ elementoanterior->proximo=elementoauxiliar->proximo; /* Libera a memoria alocada */ free(elementoauxiliar); elementoauxiliar = NULL; return 1; /*Retorna zero indicando que o elemento(no) nao foi encontrado*/ return 0; Destruir a Lista A memória é alocada para cada elemento novo que é inserido na lista. Conseqüentemente, ao terminar de usar a lista, deve-se liberar a memória utilizada. Exemplo em linguagem C para destruir a lista. void desturirlista(lista **listatotal){ lista *elementoauxiliar1, *elementoauxiliar2; elementoauxiliar1 = *listatotal; while (elementoauxiliar1!= NULL){ elementoauxiliar2 = (lista *)elementoauxiliar1->proximo; free(elementoauxiliar1); elementoauxiliar1 = elementoauxiliar2; *listatotal = NULL; 6

Listas Circulares Algumas aplicações necessitam representar conjuntos cíclicos. Por exemplo, os dias da semana ou os meses do ano. Após o último, vem sempre o primeiro novamente, reiniciando um novo ciclo. Para esses casos, podemos utilizar listas circulares. Numa lista circular, o último elemento tem como próximo o primeiro elemento da lista, formando um ciclo. A rigor, neste caso, não faz sentido falarmos em primeiro ou último elemento. A lista pode ser representada por um ponteiro para um elemento inicial qualquer da lista. A figura abaixo ilustra a representação de uma lista circular. Para percorrer os elementos de uma lista circular, visitamos todos os elementos a partir do ponteiro do elemento inicial até alcançarmos novamente esse mesmo elemento. O código abaixo exemplifica essa forma de percorrer os elementos. void percorrelistacircular(lista **listatotal){ lista *elementoauxiliar; /* Verifica se a lista estah vazia */ if (elementoauxiliar == NULL){ return; do{ printf("%d\n", elementoauxiliar->info); elementoauxiliar = (lista *)elementoauxiliar->proximo; while (elementoauxiliar!= *listatotal); 7

Listas Duplamente Encadeadas Em uma lista duplamente encadeada cada elemento (nó) tem um ponteiro para o próximo elemento e um ponteiro para o elemento anterior. Desta forma, dado um elemento, podemos acessar ambos os elementos adjacentes: o próximo e o anterior. Se tivermos um ponteiro para o último elemento da lista, podemos percorrer a lista em ordem inversa, bastando acessar continuamente o elemento anterior, até alcançar o primeiro elemento da lista, que não tem elemento anterior, ou seja, aponta para NULL. NULL NULL O elemento (nó) de uma lista duplamente encadeada pode ser representado pela estrutura abaixo. typedef struct { int info; struct lista *proximo; struct lista *anterior; lista; 8

Função main (principal) para testar a lista ligada #include <stdio.h> #include <stdlib.h> #include <conio.h> int main(int argc, char *argv[]) { lista *listatotal=null, *elemento1=null, *elemento2=null; lista *elemento3, *elemento4, *elemento5, *elementobusca; elemento1 = criarelemento(1); inseririnicio(&listatotal, elemento1); elemento2 = criarelemento(2); inseririnicio(&listatotal, elemento2); elemento3 = criarelemento(3); inserirfim(&listatotal, elemento3); elemento4 = criarelemento(4); inserirfim(&listatotal, elemento4); elemento5 = criarelemento(5); inserirmeio(&listatotal, elemento5, 3); elementobusca = buscarelemento(&listatotal, 10); /* Exemplo para remover o primeiro elemento da lista */ /* removerelemento(&listatotal, 2); */ /* Exemplo para remover o ultimo elemento da lista */ /* removerelemento(&listatotal, 4); */ /* Exemplo para remover um elemento do meio da lista */ removerelemento(&listatotal, 10); desturirlista(&listatotal); getch(); return 0; 9