unit zx.core.FixedQueue;
interface
uses
System.SysUtils, System.Generics.Collections;
type
TFixedQueue<T> = class
private
/// <summary>
/// 一个动态数组,用于存储队列元素,动态数组会自动管理内存
/// </summary>
FItems: TArray<T>;
/// <summary>
/// 头指针,指向队列的逻辑第一个元素
/// </summary>
FFront: Integer;
/// <summary>
/// 尾指针,指向队列的逻辑最后一个元素
/// </summary>
FRear: Integer;
/// <summary>
/// 当前队列中的元素数量
/// </summary>
FCount: Integer;
/// <summary>
/// 队列的固定容量
/// </summary>
FCapacity: Integer;
/// <summary>
/// 根据逻辑索引获取元素
/// </summary>
function GetItem(Index: Integer): T;
/// <summary>
/// 根据逻辑索引设置元素
/// </summary>
procedure SetItem(Index: Integer; const Value: T);
/// <summary>
/// 效仿官方的 TQueue
/// </summary>
function GetIsEmpty: Boolean; inline;
function GetIsFull: Boolean; inline;
public
constructor Create(Capacity: Integer);
procedure Enqueue(Item: T);
function Dequeue: T;
function Peek: T;
property Count: Integer read FCount;
property Capacity: Integer read FCapacity;
property IsEmpty: Boolean read GetIsEmpty;
property IsFull: Boolean read GetIsFull;
/// <summary>
/// 可以根据这个来遍历,注意 Index 其实是逻辑索引
/// for var i = 0 to count - 1 ... item[i] 就遍历了
/// </summary>
property Items[Index: Integer]: T read GetItem write SetItem;
end;
implementation
constructor TFixedQueue<T>.Create(Capacity: Integer);
begin
if Capacity <= 0 then
raise EArgumentOutOfRangeException.Create('容量必须大于0!');
FCapacity := Capacity;
SetLength(FItems, FCapacity);
FFront := 0;
FRear := -1;
FCount := 0;
end;
procedure TFixedQueue<T>.Enqueue(Item: T);
begin
if FCount = FCapacity then
raise Exception.Create('队列已满,新入队失败!');
FRear := (FRear + 1) mod FCapacity;
FItems[FRear] := Item;
Inc(FCount);
end;
function TFixedQueue<T>.Dequeue: T;
begin
if FCount = 0 then
raise Exception.Create('队列是空,无法出队!');
Result := FItems[FFront];
FFront := (FFront + 1) mod FCapacity;
Dec(FCount);
end;
function TFixedQueue<T>.Peek: T;
begin
if FCount = 0 then
raise Exception.Create('队列是空,无法 Peek!');
Result := FItems[FFront];
end;
function TFixedQueue<T>.GetItem(Index: Integer): T;
begin
if (Index < 0) or (Index >= FCount) then
raise EArgumentOutOfRangeException.Create('队列索引越界!');
Result := FItems[(FFront + Index) mod FCapacity];
end;
procedure TFixedQueue<T>.SetItem(Index: Integer; const Value: T);
begin
if (Index < 0) or (Index >= FCount) then
raise EArgumentOutOfRangeException.Create('队列索引越界!');
FItems[(FFront + Index) mod FCapacity] := Value;
end;
function TFixedQueue<T>.GetIsEmpty: Boolean;
begin
Result := FCount = 0;
end;
function TFixedQueue<T>.GetIsFull: Boolean;
begin
Result := FCount = FCapacity;
end;
end.
标签:function,Index,队列,delphi,TFixedQueue,FCount,Integer
From: https://www.cnblogs.com/del88/p/18607788