Delphi - 简单实现 优先队列

发布时间 2023-05-22 17:16:13作者: 老衲88

由于Delphi官方没有实现优先队列容器,我自己也懒得用二叉堆去实现,这里用List简单实现一个优先队列;

 

unit Unit3;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Generics.Collections, System.Generics.Defaults,
  Vcl.StdCtrls, System.SyncObjs;

type
  TForm3 = class(TForm)
    btn1: TButton;
    mmo1: TMemo;
    procedure btn1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TPerson = class
  private
    name: string;
    age: Integer;
  public
    constructor Create(name: string; age: Integer);
  end;

  /// <summary>
  /// 优先队列 - List,入队慢,出队快模式
  /// </summary>
  TPriorityQueue<T> = class
  private
    list: TList<T>;
  public
    constructor Create(const Comparison: TComparison<T>);
    destructor Destroy; override;
    function Dequeue: T;
    procedure Enqueue(item: T);
    function Count: Integer;
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

constructor TPerson.Create(name: string; age: Integer);
begin
  Self.name := name;
  Self.age := age;
end;

constructor TPriorityQueue<T>.Create(const Comparison: TComparison<T>);
begin
  inherited Create;
  list := TList<T>.Create(TComparer<T>.Construct(Comparison));
end;

destructor TPriorityQueue<T>.Destroy;
begin
  list.Free;
  inherited;
end;

function TPriorityQueue<T>.Dequeue: T;
begin
  Result := list.First;
  list.Delete(0);
end;

procedure TPriorityQueue<T>.Enqueue(item: T);
begin
  list.Add(item);
  list.Sort;
end;

function TPriorityQueue<T>.Count: Integer;
begin
  Result := list.Count;
end;

procedure TForm3.btn1Click(Sender: TObject);
var
  pque: TPriorityQueue<TPerson>;
  person: TPerson;
begin
  pque := TPriorityQueue<TPerson>.Create(
  function(const Left, Right: TPerson): Integer
  begin
    Result := Left.age - Right.age;
  end);
  pque.Enqueue(TPerson.Create('小李1', 1));
  pque.Enqueue(TPerson.Create('小李3', 3));
  pque.Enqueue(TPerson.Create('小李2', 2));

  while pque.Count > 0 do
  begin
    person := pque.Dequeue;
    mmo1.Lines.Add(person.name);
    person.Free;
  end;

  pque.Free;
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown := True;
end;

end.