unit Queue; interface type TElem = shortint; TErrCode = byte; PQueue = ^TQueue; TQueue = object private Fp: pointer; FNmax: word; { максимальное кол-во элементов } FHead, FTail: word; { хвост, голова } FErrCode: TErrCode; { код ошибки } public constructor Create(Len: word); constructor Copy(Ptr: PQueue); destructor Destroy; procedure MakeEmpty; { очищает очередь } function Empty: boolean; { очередь пуста? } function Full: boolean; { очередь полна? } function MaxLen: word; { максимальное кол-во элементов } function Push(x: TElem): boolean; { добавить элемент в очередь } function Change(x: TElem): boolean; { изменить значение головного элемента очереди } function Pop(var x: TElem): boolean; { взять элемент из головы очереди } function See(var x: TElem): boolean; { посмотреть значение головы очереди } function Del: boolean; { удалить головной элемент из очереди } function ErrCode: TErrCode; end; { TQueue } { FErrCode = 0 - ошибок нет 1 - очередь полна 2 - очередь пуста } implementation const MaxHeap = 65520; type { внутренняя реализация очереди } PArray = ^TArray; TArray = array[0..0] of TElem; constructor TQueue.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; { TQueue.Create } constructor TQueue.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; { TQueue } destructor TQueue.Destroy; begin freemem(Fp, longint(FNMax+1)*longint((sizeof(TElem)))); end; { TQueue.Destroy } procedure TQueue.MakeEmpty; begin FHead:= 0; FTail:= 0; FErrCode:= 0; end; { TQueue.MakeEmpty } function TQueue.Empty; begin Empty:= (FTail = FHead); FErrCode:= 0; end; { TQueue.Empty } function TQueue.Full; begin Full:= (FHead = (FTail + 1) mod (FNMax+1)); FErrCode:= 0; end; { TQueue.Full } function TQueue.MaxLen; begin MaxLen:= FNMax; FErrCode:= 0; end; { TQueue.MaxLen } function TQueue.Push; begin if Full then begin Push:= false; FErrCode:= 1; exit; end; PArray(Fp)^[FTail]:= x; FTail:= (FTail+1) mod (FNMax + 1); Push:= true; FErrCode:= 0; end; { TQueue.Push } function TQueue.Change; begin if Empty then begin Change:= false; FErrCode:= 2; exit; end; PArray(Fp)^[FHead]:= x; Change:= True; FErrCode:= 0; end; { TQueue.Change } function TQueue.Pop; begin if Empty then begin Pop:= false; FErrCode:= 2; exit; end; x:= PArray(Fp)^[FHead]; FHead:= (FHead + 1) mod (FNMax + 1); Pop:= true; FErrCode:= 0; end; { TQueue.Pop } function TQueue.See; begin if Empty then begin See:= false; FErrCode:= 2; exit; end; x:= PArray(Fp)^[FHead]; See:= true; FErrCode:= 0; end; { TQueue.See } function TQueue.Del; begin if Empty then begin Del:= false; FErrCode:= 2; exit; end; FHead:= (FHead + 1) mod (FNMax + 1); Del:= true; FErrCode:= 0; end; { TQueue.Del } function TQueue.ErrCode; begin ErrCode:= FErrCode; end; { ErrCode } end.