Listas em C

4,777 views
4,638 views

Published on

Listas em C
www.criatividadezero.com.br

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,777
On SlideShare
0
From Embeds
0
Number of Embeds
31
Actions
Shares
0
Downloads
96
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Listas em C

  1. 1. Listas IIProfessor William Malvezzi
  2. 2. Fontes BibliográficasWaldemar Celes, Renato Cerqueira, José LucasRangel, Introdução a Estruturas de Dados,Editora Campus (2004)Capítulo 10 – Listas encadeadas
  3. 3. Listas circularesAlgumas aplicações necessitam representarconjuntos cíclicos. Por exemplo, as arestasque delimitam uma face podem ser agrupadaspor uma estrutura circular. Para essescasos, podemos usar listas circulares.
  4. 4. Listas circularesNuma lista circular, o último elemento temcomo próximo o primeiro elemento da lista,formando um ciclo. A rigor, neste caso, não fazsentido falarmos em primeiro ou últimoelemento. A lista pode ser representada por umponteiro para um elemento inicialqualquer da lista.
  5. 5. Listas circulares
  6. 6. Listas circularesPara percorrer os elementos de uma listacircular, visitamos todos os elementos a partirdo ponteiro do elemento inicial até alcançarmosnovamente esse mesmo elemento. Ocódigo abaixo exemplifica essa forma de percorrer oselementos. Neste caso, parasimplificar, consideramos uma lista que armazena valoresinteiros. Devemos salientarque o caso em que a lista é vazia ainda deve ser tratado(se a lista é vazia, o ponteiropara um elemento inicial vale NULL).
  7. 7. Listas circularesvoid imprime_circular (Lista* l){ Lista* p = l; /* faz p apontar para o nó inicial */ /* testa se lista não é vazia */ if (p) { //* percorre os elementos até alcançar novamente o início do { printf("%dn", p->info); // imprime informação do nó p = p->prox; // avança para o próximo nó } while (p != l);}
  8. 8. Listas duplamente encadeadasO problema da Lista encadeada simples é que nãotemos como percorrer eficientemente os elementosem ordem inversa, isto é, do final para o início dalista. O encadeamento simples também dificulta aretirada de um elemento da lista. Mesmo setivermos o ponteiro do elemento que desejamosretirar, temos que percorrer a lista, elemento porelemento, para encontrarmos o elementoanterior, pois, dado um determinado elemento, nãotemos como acessar diretamente seu elemento
  9. 9. Listas duplamente encadeadasPara solucionar esses problemas, podemos formar oque chamamos de listas duplamente encadeadas.Nelas, cada elemento tem um ponteiro para opróximo elemento e um ponteiro para o elementoanterior.
  10. 10. Listas duplamente encadeadasDesta forma, dado um elemento, podemos acessarambos os elementos adjacentes: o próximo e oanterior. Se tivermos um ponteiro para o últimoelemento da lista, podemos percorrer a lista emordem inversa, bastando acessar continuamente oelemento anterior, até alcançar o primeiro elementoda lista, que não tem elemento anterior (o ponteirodo elemento anterior vale NULL).
  11. 11. Listas duplamente encadeadas
  12. 12. Listas duplamente encadeadasstruct lista2 { int info; struct lista2* ant; struct lista2* prox;};typedef struct lista2 Lista2;
  13. 13. Listas duplamente encadeadas - Inserção/* inserção no início */Lista2* insere (Lista2* l, int v){ Lista2* novo = (Lista2*) malloc(sizeof(Lista2)); novo->info = v; novo->prox = l; novo->ant = NULL; /* verifica se lista não está vazia */ if (l != NULL) l->ant = novo; return novo;}• Nessa função, o novo elemento é encadeado no início da lista. Assim, ele tem como próximo elemento o antigo primeiro elemento da lista e como anterior o valor NULL.
  14. 14. Listas duplamente encadeadas - Inserção
  15. 15. Listas duplamente encadeadasFunção que retira um elemento da listaA função de remoção fica mais complicada, poistemos que acertar o encadeamento duplo. Emcontrapartida, podemos retirar um elemento da listaconhecendo apenas o ponteiro para esse elemento.Desta forma, podemos usar a função de busca acimapara localizar o elemento e em seguida acertar oencadeamento, liberando o elemento aofinal.
  16. 16. Função que retira um elemento da listaSe p representa o ponteiro do elemento quedesejamos retirar, para acertar o encadeamentodevemos conceitualmente fazer: p->ant->prox = p->prox; p->prox->ant = p->ant;isto é, o anterior passa a apontar para o próximoe o próximo passa a apontar para o anterior.
  17. 17. Implementação da função para retirar um elemento/* função retira: retira elemento da lista */Lista2* retira (Lista2* l, int v) { Lista2* p = busca(l,v); if (p == NULL) return l; /* não achou o elemento: retorna lista inalterada */ /* retira elemento do encadeamento */ if (l == p) l = p->prox; else p->ant->prox = p->prox; if (p->prox != NULL) p->prox->ant = p->ant; free(p); return l;}
  18. 18. O Problema de JosephusSegundo o historiador Josephus quando de seu relato a respeitodo cerco de Yodfat (The Jewish War, Capítulo 8 verso 7), ele e41 soldados estavam cercados por uma força inimigaesmagadora, de romanos. Não havia esperanças de vitória, então decidiram o suicídio . Os soldados entraram em umacordo para determinar qual deles deveria morrer primeiro eassim uma sequência de mortes até que restasse somente um.Eles formaram um circulo onde um número (M=3) foisorteado, e um nome também foi também sorteado.Começando pelo nome do soldado sorteado, se inicia a contarao longo do circulo em sentido horário. Quando a contagemalcança M esse soldado é morto, e a contagem se reinicia com osoldado seguinte. O processo continua de maneira que, toda vezque M é atingido, outro soldado é assassinado. Todo soldadoretirado não entra mais no círculo e o ultimo soldado que sobraré o sobrevivente.
  19. 19. O Problema de JosephusConsiderando uma Lista Circular com N nomes desoldados e considerando que M será informado pelousuário, e M e deverá ser um valor inteiro. Faça umalgoritmo e programa modularizado em linguagem Cque resolva o problema de Josephus. Usemodularização para resolver o problema.

×