Домой | Софт | Мастерская | Лирика | ЧаВО | Юмор | 197-577-902 |
Дек является симбиозом стека и очереди - это та же структура, но на этот раз с ней можно работать с обеих концов. Таким образом, если мы будем работать с деком только с левого края, то фактически получается стек. Аналогично мы получим стек, если будем работать только с правого края (конца дека). Пользуясь предписаниями "добавить в конец" и "взять из начала", мы сможем получить очередь, элементы которой будут продвигаться справа налево. Название дека произошло от сокращения английских слов 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 |
|