Prof. Adriano Teixeira de Souza
   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
   Na lista de afazeres anterior, uma tarefa
    dependia da execução da tarefa anterior




                                     Próxima
                  Ação atual           ação
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
   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
   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
   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.
   Segunda opção: ponteiros
    ◦ Estruturas de dados dinâmicas: estruturas de dados
      que contém ponteiros para si próprias.



        class Lista {
           String nomeTarefa;
           float duracao;
           String responsavel;
           ...
                                       Referência para a
           Lista prox;
                                       própria classe Lista
        };
   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.
   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   /
   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).
   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
class NoLista {

    float   info;
    NoLista proximo;

    public NoLista(float valor)
    {
       this.info = valor;
       this.proximo = null;
    }

}




                        Prof. Adriano Teixeira de Souza
   Para criar a lista propriamente dita, criaremos
    a classe Lista, que manipula objetos do tipo
    NoLista
class Lista {
  NoLista inicio;

    public Lista() {
      this.inicio = null;
    }
    // insere valor no começo da lista
    public void inserir(int valor) {...}
    // insere valor no fim da lista
    public void inserirNoFim(int valor) {...}
}
   Podemos inserir itens:
    ◦ No início de uma lista
    ◦ No final de uma lista
    ◦ No meio de uma lista
   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
public void inserir(float valor) {
  if (this.inicio == null) {
    // lista vazia, então só é preciso criar o nó
    this.inicio = new NoLista(valor);
  } else {
        // cria-se novo no e atualiza o NoLista inicio
        NoLista novoNo = new NoLista(valor);
        novoNo.proximo = this.inicio;
        this.inicio = novoNo;
    }
}




                                Prof. Adriano Teixeira de Souza
   O endereço armazenado em p será alterado caso
    a lista esteja vazia ou
   O campo proximo do último item será alterado.



         /



         p      3   /



         p      3           5   /
public void inserirNoFim(int valor) {
  if (this.inicio == null) {
    // lista vazia
    this.inicio = new NoLista(valor);
  } else {
    // procura pelo fim da lista
    NoLista atual = this.inicio;
    while (atual.proximo != null)
      atual = atual.proximo;
    // insere o nó no fim da lista
    atual.proximo = new NoLista(valor);
  }
}

                     Prof. Adriano Teixeira de Souza
   Campo proximo do item a ser inserido recebe
        o campo proximo do item posterior
       Campo proximo do item antecessor recebe o
        endereço do item a ser inserido



p           3               2                 4   /


                            5


                lista[5].proximo ← lista[2]

                lista[3].proximo ← 5
   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   /
   O campo proximo do último item será alterado
    caso a lista contenha mais de um item ou

   O endereço armazenado em p será alterado para
    null caso tenha somente um elemento.

         p      3           5   /



         p      3   /



         /
   Item antecessor recebe o campo proximo do
        item a ser removido


                lista[3].proximo ← lista[5].proximo




p           3            5              2             4   /
void retira (float v) {//Em qualquer posicao

    NoLista ant = null;
    NoLista p = this.inicio;

    while (p != null && p.info != v) {
       ant = p;
       p = p.proximo;
    }
    if (p != null){
      if (ant == null) {
         this.inicio = p.proximo;
      }else {
         ant.proximo = p.proximo;
      }
    };
}
NoLista busca (float v){
    int i=0;
    for (NoLista p = this.inicio; p!=null; p=p.proximo){
        if(p.info == v){
           System.out.println("nnachou “+i+”nn");
           return p;
        }
        i++;
    }
    return null;
}




                           Prof. Adriano Teixeira de Souza
void imprime (){
  for(NoLista q=this.inicio;q!=null; q=q.proximo)
     System.out.println(q.info);
}




                        Prof. Adriano Teixeira de Souza
public static void main(String[] args){

    Lista l = new Lista();
    l.inserir(20.0f);
    l.inserir(44.5f);
    l.inserir(33.3f);
    l.inserir(20.9f);
    l.imprime();
    NoLista n = l.busca(20.9f);//Busca
    if (n != null){
       System.out.println("Encontrado:"+n.info);
       l.retira(n.info);
    }
    System.out.println("Configuracao da lista:");
    l.imprime();
    //Libera memoria
    l = null;

}

                          Prof. Adriano Teixeira de Souza
void insereOrdenado ( float valor)
{
       NoLista novoNo = new NoLista(valor );

      NoLista ant = null;
      NoLista p = this.inicio;

      while (p != null && p.info < valor) {
             ant = p;
             p = p.proximo;
      }
      if (ant == null) {
             novoNo.proximo = this.inicio;
             this.inicio = novoNo;
      } else {
             novoNo.proximo = ant.proximo;
             ant.proximo = novoNo;
      }
}

                          Prof. Adriano Teixeira de Souza
   Adicionado a C# 2.0 e posteriormente a Java 5
   Classes Genéricas, que utilizam o conceito de “parâmetros tipo”<..>
   Lista com Genéricos: cada lista armazena um tipo específico, sem
    precisar criar código novo para cada tipo

        Sem Genéricos:
                                            Com Genéricos:
    class NoListaI{
      int valor;
      NoLista next;                     class NoLista<E> {
    }                                     E elemento;
                                          NoLista<E> next;
    class NoListaS{                     }
      String nome;
      NoLista next;
    }
class Lista<E> {
  NoLista<E> inicio;

    public Lista() {
      this.inicio = null;
    }
    public void inserir(E elemento) {
      if (this.inicio == null) {
        this.inicio = new NoLista<E>(elemento);
      } else {
            NoLista<E> novoNo = new NoLista<E>(elemento);
            novoNo.next = this.inicio;
            this.inicio = novoNo;
        }
    }
}

Estrutura de dados em Java - Filas

  • 1.
  • 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. class Lista { String nomeTarefa; float duracao; String responsavel; ... Referência para a Lista prox; própria classe 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
  • 13.
    class NoLista { float info; NoLista proximo; public NoLista(float valor) { this.info = valor; this.proximo = null; } } Prof. Adriano Teixeira de Souza
  • 14.
    Para criar a lista propriamente dita, criaremos a classe Lista, que manipula objetos do tipo NoLista class Lista { NoLista inicio; public Lista() { this.inicio = null; } // insere valor no começo da lista public void inserir(int valor) {...} // insere valor no fim da lista public void inserirNoFim(int valor) {...} }
  • 15.
    Podemos inserir itens: ◦ No início de uma lista ◦ No final de uma lista ◦ No meio de uma lista
  • 16.
    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
  • 17.
    public void inserir(floatvalor) { if (this.inicio == null) { // lista vazia, então só é preciso criar o nó this.inicio = new NoLista(valor); } else { // cria-se novo no e atualiza o NoLista inicio NoLista novoNo = new NoLista(valor); novoNo.proximo = this.inicio; this.inicio = novoNo; } } Prof. Adriano Teixeira de Souza
  • 18.
    O endereço armazenado em p será alterado caso a lista esteja vazia ou  O campo proximo do último item será alterado. / p 3 / p 3 5 /
  • 19.
    public void inserirNoFim(intvalor) { if (this.inicio == null) { // lista vazia this.inicio = new NoLista(valor); } else { // procura pelo fim da lista NoLista atual = this.inicio; while (atual.proximo != null) atual = atual.proximo; // insere o nó no fim da lista atual.proximo = new NoLista(valor); } } Prof. Adriano Teixeira de Souza
  • 20.
    Campo proximo do item a ser inserido recebe o campo proximo do item posterior  Campo proximo do item antecessor recebe o endereço do item a ser inserido p 3 2 4 / 5 lista[5].proximo ← lista[2] lista[3].proximo ← 5
  • 21.
    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 /
  • 22.
    O campo proximo do último item será alterado caso a lista contenha mais de um item ou  O endereço armazenado em p será alterado para null caso tenha somente um elemento. p 3 5 / p 3 / /
  • 23.
    Item antecessor recebe o campo proximo do item a ser removido lista[3].proximo ← lista[5].proximo p 3 5 2 4 /
  • 24.
    void retira (floatv) {//Em qualquer posicao NoLista ant = null; NoLista p = this.inicio; while (p != null && p.info != v) { ant = p; p = p.proximo; } if (p != null){ if (ant == null) { this.inicio = p.proximo; }else { ant.proximo = p.proximo; } }; }
  • 25.
    NoLista busca (floatv){ int i=0; for (NoLista p = this.inicio; p!=null; p=p.proximo){ if(p.info == v){ System.out.println("nnachou “+i+”nn"); return p; } i++; } return null; } Prof. Adriano Teixeira de Souza
  • 26.
    void imprime (){ for(NoLista q=this.inicio;q!=null; q=q.proximo) System.out.println(q.info); } Prof. Adriano Teixeira de Souza
  • 27.
    public static voidmain(String[] args){ Lista l = new Lista(); l.inserir(20.0f); l.inserir(44.5f); l.inserir(33.3f); l.inserir(20.9f); l.imprime(); NoLista n = l.busca(20.9f);//Busca if (n != null){ System.out.println("Encontrado:"+n.info); l.retira(n.info); } System.out.println("Configuracao da lista:"); l.imprime(); //Libera memoria l = null; } Prof. Adriano Teixeira de Souza
  • 28.
    void insereOrdenado (float valor) { NoLista novoNo = new NoLista(valor ); NoLista ant = null; NoLista p = this.inicio; while (p != null && p.info < valor) { ant = p; p = p.proximo; } if (ant == null) { novoNo.proximo = this.inicio; this.inicio = novoNo; } else { novoNo.proximo = ant.proximo; ant.proximo = novoNo; } } Prof. Adriano Teixeira de Souza
  • 29.
    Adicionado a C# 2.0 e posteriormente a Java 5  Classes Genéricas, que utilizam o conceito de “parâmetros tipo”<..>  Lista com Genéricos: cada lista armazena um tipo específico, sem precisar criar código novo para cada tipo Sem Genéricos: Com Genéricos: class NoListaI{ int valor; NoLista next; class NoLista<E> { } E elemento; NoLista<E> next; class NoListaS{ } String nome; NoLista next; }
  • 30.
    class Lista<E> { NoLista<E> inicio; public Lista() { this.inicio = null; } public void inserir(E elemento) { if (this.inicio == null) { this.inicio = new NoLista<E>(elemento); } else { NoLista<E> novoNo = new NoLista<E>(elemento); novoNo.next = this.inicio; this.inicio = novoNo; } } }