Лекции по информатике - Дек (deq)

Общая информация

Дек является симбиозом стека и очереди - это та же структура, но на этот раз с ней можно работать с обеих концов. Таким образом, если мы будем работать с деком только с левого края, то фактически получается стек. Аналогично мы получим стек, если будем работать только с правого края (конца дека). Пользуясь предписаниями "добавить в конец" и "взять из начала", мы сможем получить очередь, элементы которой будут продвигаться справа налево. Название дека произошло от сокращения английских слов Double Ended Queue - очередь с двумя концами.

Пример реализации "ограниченного" дека на Паскале

Приведем пример реализации ограниченного дека на turbo pascal, основанного на динамическом одномерном массиве.

unit Deq;

interface

type
  TElem = char;
  TErrCode = byte;

  PDeq = ^TDeq;
  TDeq = object
  private
    Fp: pointer;
    FNmax: word;
      { максимальное кол-во элементов }
    FHead, FTail: word;
      { хвост, голова }
    FErrCode: TErrCode; 
      { код ошибки }
  public
    constructor Create(Len: word);
    constructor Copy(Ptr: PDeq);
    destructor Destroy;
    procedure MakeEmpty;
      { очищает дек }
    function Empty: boolean;
      { дек пуст? }
    function Full: boolean;
      { дек полон? }
    function MaxLen: word;
      { максимальное кол-во элементов }

    function PushH(x: TElem): boolean;    
      { добавить элемент в голову дека }
    function PushT(x: TElem): boolean;    
      { добавить элемент в хвост дека }
    function PopH(var x: TElem): boolean; 
      { взять элемент из головы дека }
    function PopT(var x: TElem): boolean;
      { взять элемент из хвоста дека }
    function ChangeH(x: TElem): boolean;  
      { изменить значение головного элемента }
    function ChangeT(x: TElem): boolean;  
      { изменить значение хвостового элемента }
    function SeeH(var x: TElem): boolean; 
      { посмотреть значение головы дека }
    function SeeT(var x: TElem): boolean; 
      { посмотреть значение хвоста дека }
    function DelH: boolean;               
      { удалить головной элемент из дека }
    function DelT: boolean;               
      { удалить хвостовой элемент из дека }
    function ErrCode: TErrCode;
  end;

implementation

const
  MaxHeap = 65520;

type
{ внутренняя реализация дека }
  PArray = ^TArray;
  TArray = array[0..0] of TElem;

constructor TDeq.Create;
var
  mem: longint;
begin
  if Len <= 0 then
    begin
      Fail;
      exit;
    end;

  mem:= (longint(Len) + 1) * longint(sizeOf(TElem));
{ необходимый размер свободной памяти }
  if (mem > MaxAvail) or (mem > MaxHeap) then
    begin
      fail;
      exit;
    end;

  getmem(Fp, mem);
  FNMax:= Len;
{ признак пустого дека }
  FHead:= 0;
  FTail:= 0;
  FErrCode:= 0;
end; { TDeq.Create }

constructor TDeq.Copy;
var
  mem: longint;
  i: word;
begin
  if Ptr = nil then
    begin
      Fail;
      exit;
    end;

  mem:= (longint(Ptr^.MaxLen) + 1) * longint(sizeof(TElem));
{ необходимый размер свободной памяти }
  if (mem > MaxAvail) or (mem > MaxHeap) then
    begin
      fail;
      exit;
    end;

  getmem(Fp, mem);
  FHead:= Ptr^.FHead;
  FTail:= Ptr^.FTail;
{ копируем элементы из исходного дека }
  for i:= 0 to Ptr^.MaxLen do
    PArray(Fp)^[i]:= PArray(Ptr^.Fp)^[i];
  FNMax:= Ptr^.MaxLen;
  FErrCode:= 0;
end; { TDeq.Copy }

destructor TDeq.Destroy;
begin
  freemem(Fp, longint(FNMax+1)*longint((sizeof(TElem))));
end; { TDeq.Destroy }

procedure TDeq.MakeEmpty;
begin
  FHead:= 0;
  FTail:= 0;
  FErrCode:= 0;
end; { TDeq.MakeEmpty }

function TDeq.Empty;
begin
  Empty:= (FTail = FHead);
  FErrCode:= 0;
end; { TDeq.Empty }

function TDeq.Full;
begin
  Full:= (FHead = (FTail + 1) mod (FNMax+1));
  FErrCode:= 0;
end; { TDeq.Full }

function TDeq.MaxLen;
begin
  MaxLen:= FNMax;
  FErrCode:= 0;
end; { TDeq.MaxLen }

function TDeq.PushH;
begin
  if Full then
    begin
      PushH:= false;
      FErrCode:= 1;
      exit;
    end;

  FHead:= (longint(FHead)-1) mod (FNMax + 1);
  PArray(Fp)^[FHead]:= x;
  PushH:= true;
  FErrCode:= 0;
end; { TDeq.PushH }

function TDeq.PushT;
begin
  if Full then
    begin
      PushT:= false;
      FErrCode:= 1;
      exit;
    end;

  PArray(Fp)^[FTail]:= x;
  FTail:= (FTail+1) mod (FNMax + 1);
  PushT:= true;
  FErrCode:= 0;
end; { TDeq.PushT }

function TDeq.ChangeH;
begin
  if Empty then
    begin
      ChangeH:= false;
      FErrCode:= 2;
      exit;
    end;

  PArray(Fp)^[FHead]:= x;
  ChangeH:= True;
  FErrCode:= 0;
end; { TDeq.ChangeH }

function TDeq.ChangeT;
begin
  if Empty then
    begin
      ChangeT:= false;
      FErrCode:= 2;
      exit;
    end;

  PArray(Fp)^[(longint(FTail) - 1) mod (FNMax+1)]:= x;
  ChangeT:= True;
  FErrCode:= 0;
end; { TDeq.ChangeT }

function TDeq.PopH;
begin
  if Empty then
    begin
      PopH:= false;
      FErrCode:= 2;
      exit;
    end;

  x:= PArray(Fp)^[FHead];
  FHead:= (FHead + 1) mod (FNMax + 1);
  PopH:= true;
  FErrCode:= 0;
end; { TDeq.PopH }

function TDeq.PopT;
begin
  if Empty then
    begin
      PopT:= false;
      FErrCode:= 2;
      exit;
    end;

  FTail:= (longint(FTail) - 1) mod (FNMax + 1);
  x:= PArray(Fp)^[FTail];
  PopT:= true;
  FErrCode:= 0;
end; { TDeq.PopT }

function TDeq.SeeH;
begin
  if Empty then
    begin
      SeeH:= false;
      FErrCode:= 2;
      exit;
    end;

  x:= PArray(Fp)^[FHead];
  SeeH:= true;
  FErrCode:= 0;
end; { TDeq.SeeH }

function TDeq.SeeT;
begin
  if Empty then
    begin
      SeeT:= false;
      FErrCode:= 2;
      exit;
    end;

  x:= PArray(Fp)^[(longint(FTail) - 1) mod (FNMax + 1)];
  SeeT:= true;
  FErrCode:= 0;
end; { TDeq.SeeT }

function TDeq.DelH;
begin
  if Empty then
    begin
      DelH:= false;
      FErrCode:= 2;
      exit;
    end;

  FHead:= (FHead + 1) mod (FNMax + 1);
  DelH:= true;
  FErrCode:= 0;
end; { TDeq.DelH }

function TDeq.DelT;
begin
  if Empty then
    begin
      DelT:= false;
      FErrCode:= 2;
      exit;
    end;

  FTail:= (FTail - 1) mod (FNMax + 1);
  DelT:= true;
  FErrCode:= 0;
end; { TDeq.DelT }


function TDeq.ErrCode;
begin
  ErrCode:= FErrCode;
end; { TDeq.ErrCode }

end.

Реализация класса "дек" на С++

 

Слава Антонов © 2002 — August 13, 2008
Индекс цитирования
Hosted by uCoz