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;
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.