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.
本文来自博客园,作者:del88,转载请注明原文链接:https://www.cnblogs.com/del88/p/18607788
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人