Índice > Lista > Generalizada > Operações

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

Operações

Definição:

Type
    pont_no = ^no;
    no = record
            cauda: pont_no;
            case tag: boolean of
                true: (pont: pont_no);
                false: (atomo: tipo_elem);
    End;
    Lista = pont_no;
Para definir uma implementação para Listas Generalizadas, definimos alguns termos:

Operações usuais em Lista Generalizada

Algumas operações típicas de Lista Generalizada são:
Obs: retorno das operações em itálico.
cabeça (lista,valor)
    Fornece o valor do primeiro elemento de lista (a cabeça).
cauda (lista1,lista2)
    Fornece a lista obtida removendo-se do primeiro elemento de lista (a cabeça) -
       isto é, o ponteiro para a cauda.
primeiro (lista, elem)
    Retorna o elemento correspondente à cabeça da lista.
info (elem, valor)
    Retorna o valor correspondente ao elemento elem.
próximo (elem, proxElem)
    Retorna o elemento seguinte ao elemento elem da lista.
tipo_nó (elem,tipo)
    Retorna o tipo do elemento, isto é, se ele é lista ou átomo.
define_cabeça (lista, x:no)
    Substitui a cabeça da lista pelo elemento dado por x.
insere_início (lista, x:no, lista1)
    Insere um elemento no início da lista, mas não altera a cabeça da lista.
    Retorna um ponteiro para essa 'nova' lista em lista1.
define_próximo (elem1, elem2)
    Substitui o próximo elemento a elem1 por elem2. Como tudo em elem2 fica intacto,
    essa operação é equivalente a trocar todo o restante da lista que contem elem1, a
    a partir do próximo elemento.
define_cauda (l, list1)
    Define a lista list1 como sendo a cauda da lista l.
define_info (elem, valor)
    Atribui valor ao conteúdo do elemento elem.
vazia (list)
    Determina se a lista list está vazia
inicializa (list)
    Inicializa list como uma lista vazia.
esvazia (list)
    Torna a lista vazia.
Algoritmos Baseados nas Operações Acima
Suponha que se deseja criar as seguintes listas:
Lista 1
Lista 2
Qual a sequência das operações acima para construção da lista acima?
-> Refazer a sequência de operações após definir as operações, isto é, definindo os
  comandos Pascal para construção da lista.
Definição de algumas operações: supondo implementação sem cabeçalho
Function primeiro (lista:pont_no): pont_no;
Begin
    primeiro:=lista;
End;
-> Perguntas: Por que, em Pascal, é necessário retornar o ponteiro?
              Porque é razoável contruir a Function primeiro, se ela retorna a
                própria lista?
Procedure próximo (elem: pont_no; VAR proxElem:pont_no);
Begin
    proxElem:= pont_no^.cauda;
End;
Procedure info_el (elem:pont_no; Var valor:tipo_elem);
Begin
    if (not elem^.tag) then valor:=elem^.atomo
    else valor:= valorNulo;
End;


Procedure info_l (elem:pont_no; Var lista:pont_no);
Begin
    if (elem^.tag) then lista:=elem^.pont
    else valor:= pontNulo;
End;
-> Necessidade de determinar um elemento nulo - > usuário
-> Se o registro do elemento, na definição do início da página, fosse feita mais
adequadamente, seria possível retornar a informação de um nó por uma única operação,
info, que retornaria o conteúdo (ponteiro ou átomo) e o tipo do conteúdo.
Procedure define_cabeça (lista: pont_no; x:no)
var p:pont_no;
Begin
    x^.cauda = lista^.cauda;
    lista^:=x;
End;
Function insere_início (lista:pont_no, x:no): pont_no;
var p:pont_no;
Begin
    new(p);
    p^:=x;
    p^.cauda := lista;
    insere_início := p;
End;
Procedure define_próximo (elem1, elem2:pont_no);
var p:pont_no;
Begin
    p:= elem1^.cauda;
    elem1^.cauda:=elem2;
   -> -> O que fazer com a antiga cauda, isto é, o resto da lista a partir de elem1?
End;
Procedure define_cauda (l, list1: pont_no);
Begin
    define_próximo (l,list1);
End
Procedure define_info (elem: pont_no, valor:no);
-> Atenção. Aqui, seria melhor se o objeto da lista estivesse definido como
        conteúdo (atomo ou lista+tag) e cauda, em dois campos separados.
Begin
    valor^.cauda = elem^.cauda;
    elem^:=valor;
End;
Procedure tipo_nó (elem:no): boolean;
-> Aqui seria melhor se o tipo do elemento fosse definido por enumeração.
Begin
    tipo_nó:= elem^.tag;
End;
-> Completar a definição das operações acima
-> Fazer as alterações sugeridas acima para o tipo lista, e re-fazer todas as
operações para o novo tipo. As alterações sugeridas são:
            . Usar tipo enumerado, ao invés de boolean, para definir o
                conteúdo de um nó.
            . Separar o registro referente a um elemento da lista em dois, um
                contento o conteúdo (ou info), que contém tag e valor (seja ele
                ponteiro ou atomo), e o outro contendo o ponteiro para o próximo
                (ou cauda).
            Lembre-se de definir uma única operação info.
-> Considerar condições de erro, pré-condições e pós-condições das operações
    definidas acima.
-> Re-fazer as operações, considerando que lista tem um cabeçalho.
-> Fazer busca
-> Extrair o TAD, e implementar as operações de interface do mesmo.
-> Implementar as demais operações

Exercícios

Listas Generalizadas