Índice > Lista > Estática Encadeada > Algoritmos de Manipulação

Instituto de Ciências Matemáticas de São Carlos 
Departamento de Computação e Estatística 
SCE182 - Algoritmos e Estruturas de Dados 1 
Profs. Resp.: Graça Pimentel,  Maria Cristina e Rosane

Algoritmos de Manipulação

Supondo apenas um campo de informação do tipo T:

  Const N=_____; {número máximo de elementos}
  Type endereço= 0..N; { elementos armazenados nas posições de 
                         1 a N do array; o valor 0 indica fim 
                         da lista }
  Type Rec = record
               info: T
               lig:  endereço;
             End;

      Lista = record
                A: array[1..N] of Rec;
                Prim, Dispo: endereco;
             End;

  Var L: lista;
1) Qual é o primeiro elemento da lista ?
  Function Primeiro (L: lista): T;
  Begin
    If L.Prim <> 0 Then
      Primeiro := L.A[L.Prim].info;
  End;
2) Qual é o último ?
  Function Ultimo(L: Lista): T;
  Var p: endereco;
  Begin
    If L.Prim = 0 Then 
      {Retorna lista vazia }
    Else
      Begin
        p := L.Prim;
        While L.A[p].lig <> 0 do
          p := L.A[p].lig;         {L.A[p].info é o último elemento}
      End;
    Ultimo := L.A.[p].info;
  End;
3) Quantos elementos tem a lista ?
  Function No_elementos(L: Lista): integer;
  Var Nelem: integer;
      p: endereco;
  Begin
    If L.Prim = 0 Then            
      Nelem := 0     {lista vazia}
    Else                   
      Begin                  
        p := L.Prim;        
        Nelem := 1;         
        While L.A[p].lig <> 0 do
          Begin             
            Nelem := Nelem + 1;   {Nelem contém o Número de elementos}
            p := L.A[p].lig;
          End;             
      End;           
    No_elementos := Nelem;
End;

Algoritmos para inserção e eliminação de elementos

Os algoritmos requerem a mudança de vários ponteiros: do antecessor do registro na lista, do ponteiro da lista Dispo, e do registro a ser inserido/eliminado.

Temos ObterNo(j) e DevolverNo(j), as quais permitem obter um registro de índice j da Dispo, ou devolver o registro de indice j, respectivamente.

Na inserção podemos contar com o registro j como sendo disponível, e na eliminação podemos contar com o registro j como a ser deixado disponível.

Para inserir ou eliminar um elemento da lista, temos que saber do endereço do predecessor (lembre que a busca é guiada pelo conteúdo do registro, no caso de listas ordenadas). Este predecessor é quem contém o endereço daquele que será o sucessor do elemento inserido/eliminado.

inserção

eliminação

1) Inserção após o registro de endereço k

  Procedure Insere(var L: Lista; k: endereco, valor: T);
  Var j: endereco;
  Begin
    If L.Dispo <> 0 Then      {se a Dispo está vazia, nao pode inserir!}
      Begin                   
        ObterNo(j);            
        L.A[j].info := valor;
        L.A[j].lig  := L.A[k].lig;
        L.A[k].lig  := j;
      End                 
    Else             {não pode inserir registro} 
     ...
  End;
-> Fazer a inserção de um novo registro na lista APÓS o m-ésimo registro da lista.
Usar o procedimento Insere acima no código.
2) Eliminação do registro de endereço j precedido por k
  Procedure Remove(var L: Lista; k,j: endereco);
  Begin
    L.A[k].lig := L.A[j].lig;
    DevolverNo(j);         
  End;
-> Fazer a remoção do m-ésimo registro da lista.
Usar o procedimento Remove acima no código, e retornar o conteúdo do registro
sendo removido.
3) Casos especiais

Inserção antes do primeiro elemento

  Procedure Insere_prim(var L: Lista; valor: T);
  Var j: endereco;
  Begin
    If L.Dispo <> 0 Then
      Begin
        ObterNo(j);
        L.A[j].info:= valor;
        L.A[j].lig := L.Prim;
        L.Prim := j;
      End
    Else
      { não pode inserir }  
  End;
OBS: No caso da lista estar vazia, Prim passar a apontar o único elemento da lista.

Inserção em lista vazia

  Procedure Insere_ListaVazia(var L: Lista; valor: T);
  Var j: endereco;
  Begin
    If L.Dispo <> 0 Then   { lista vazia ou prim = 0 }
      Begin
        Obter_No(j);
        L.A[j].info:=valor;
        L.A[j].lig:=0;  {null}
        L.Prim:=j;
      End;
  End;
Eliminação do primeiro elemento

  Procedure Remove_Primeiro(var L: Lista);
  Var j: endereco;
  Begin
    j := L.Prim;
    L.Prim := L.A[L.Prim].lig;
    DevolverNo(j);  
  End;
4) Acesso ao i-ésimo elemento A[i].info
  Function Acessa_iesimo(L: Lista; Var dado: T): boolean;
  Var p,j: endereço;
  Begin
    p := L.Prim;  { começa do primeiro elemento }
    j := 1;         
    While (j < i) and (p <> 0) do
      Begin
        p := L.A[p].lig;           { fim := (p=0)   }
        j := j + 1;              { achou := (j=i) }
      End;
    If p = 0 Then 
      Begin     
        Acessa_iesimo:=false;{ lista não possui i elementos }
        dado:=0;
      End       
    Else 
      Begin
        Acessa_iesimo:=true;    
       dado:=L.A[p].info;  { A[p] é o elemento procurado}
      End;
  End;
5) Eliminar o registro de conteúdo dado pela variável valor
  Procedure Remove_elem(var L: lista; valor: T);
  Var pa, p, endereco;
      acabou: boolean;
  Begin
    pa := 0;              { ponteiro anterior }
    p  := L.Prim;           { busca a partir do primeiro }
    acabou := (p=0);      { termina quando fim da lista ]
    While not (acabou) do
      Begin
        If L.A[p].info <> valor Then
          Begin
            pa := p;
            p := L.A[p].lig;
            acabou := (p=0);
          End
        Else 
          acabou := true;
      End;
            
    If p=0 Then 
      { não existe o conteúdo `valor' na lista }
    Else
      Begin
        If pa = 0 Then 
          L.Prim := L.A[L.Prim]lig;   { eliminar o primeiro elemento }
        Else 
          L.A[pa].lig := L.A[p].lig;
        DevolverNo(p);
      End;
  End;
-> Da forma como foram definidos, os procedimentos ObterNo() e DevolverNo(),
consideram a Lista Encadeada como uma variável global (verifique), o que não é uma
 boa idéia. Alterá-los para passar a Lista como parâmetro.
-> A Busca pode (e deve) ser executada por um algoritmo especificamente projetado
para isso. Fazer o algoritmo de busca para lista Estática Encadeada, e substituir
os trechos correspondentes dos algoritmos acima, pela chamada ao algoritmo de busca.
-> Refazer os algortimos acima utilizando uma estrutura parecida com a utilizada em
em Lista Estática Sequencial, isto é, com o registro contendo número de elementos
(Nelem) e com o campo de dado contendo chave e info. Nesse caso, Busca deverá ser
feita pelo valor da chave.
-> Listar as operações adequadas para o TAD Lista Estática Encadeada Ordenada, nos
moldes da TAD lista inicial. Obs: Busca deve ser uma operação realizada
individualmente.
-> desenvolver os algoritmos para todas as suas operações do TAD acima, usando
a estrutura que contém um campo chave. A operação de Busca deve ser utilizada por
todas as demais operações que necessitarem de buscas.

Lista Estática Encadeada

Algoritmos de Busca