program FilaApontadores;

type
  TipoChave     = integer;
  TipoApontador = ^TipoCelula;
  TipoItem      = record
                    Chave: TipoChave;
                    { outros componentes }
                  end;
  TipoCelula    = record 
                    Item: TipoItem;
                    Prox: TipoApontador;
                  end;
  TipoFila      = record
                    Frente: TipoApontador;
                    Tras  : TipoApontador;
                  end;

procedure FFVazia (var Fila: TipoFila);
begin
  new (Fila.Frente);
  Fila.Tras := Fila.Frente; Fila.Frente^.Prox := nil;
end; { FFVazia }

function Vazia (Fila: TipoFila): boolean;
begin Vazia := Fila.Frente = Fila.Tras; end; 

procedure Enfileira (x: TipoItem; var Fila: TipoFila);
begin
  new (Fila.Tras^.Prox); Fila.Tras := Fila.Tras^.Prox;
  Fila.Tras^.Item := x;  Fila.Tras^.Prox := nil;
end; { Enfileira }

procedure Desenfileira (var Fila: TipoFila; var Item: TipoItem);
var q: TipoApontador;
begin
  if Vazia (Fila)
  then writeln ('Erro: fila esta vazia')
  else begin
       q := Fila.Frente; Fila.Frente := Fila.Frente^.Prox;
       Item := Fila.Frente^.Item; dispose (q);
       end;
end; { Desenfileira }

const MAX = 10;

var
  Fila : TipoFila;
  item : TipoItem;
  Vetor: array [1..MAX] of integer;
  p    : TipoApontador;
  i, j, k, n: integer;

begin
  FFVazia (Fila);
  
  { Gera uma permutação aleatoria de chaves entre 1 e MAX }
  randomize;
  for i := 1 to MAX do Vetor[i] := i;
  for i := 1 to MAX do
    begin
    k := 1 + random (MAX);
    j := 1 + random (MAX);
    n := Vetor[k];
    Vetor[k] := Vetor[j];
    Vetor[j] := n;
    end;
  
  { Enfileira cada chave }
  for i := 1 to MAX do
    begin
    item.Chave := Vetor[i];
    Enfileira (item, Fila);
    writeln ('Enfileirou: ', item.Chave);
    end;
  
  { Desenfileira cada chave }
  for i := 1 to MAX do
    begin
    Desenfileira (Fila, item);
    writeln ('Desenfileirou: ', item.Chave);
    end;
end. { FilaApontadores }

