{ Example program for the grbtree unit (see http://www.vanwal.nl/rbtree/ 
  for more information) }
{$mode objfpc}
program RBTreeExample;

uses
  SysUtils, grbtree;

{ Function used as comparison function for a TRBTree of integer pointers }
function CompareInt(const i1, i2: integer): Integer;
begin
  if (i1 < i2) then begin
    Result := -1;
  end else if (i1 = i2) then begin
    Result := 0;
  end else begin
    Result := 1;
  end
end;

Type TMyRBTree = specialize TRBTree<integer>;

var
  i: Integer;
  rnd: integer;
  intTree: TMyRBTree;
  it: TMyRBTree.TRBNodeP;
begin
  Randomize;
  
  writeln('Creating intTree using CompareInt function');
  intTree := TMyRBTree.Create(@CompareInt);
  
  writeln('Adding 50 random numbers to intTree:');
  for i := 1 to 50 do begin
    rnd := Random(50);
    writeln('  ', rnd);
    intTree.Add(rnd);
    { NOTE: Add() returns the inserted TRBNodeP, but it was not necessary
            in this example. }
  end;

  Writeln('Elements in order:');
  it := intTree.First;
  while it <> intTree.Last do begin
    writeln('  ', it^.k);
    TMyRBTree.RBInc(it);
  end;
  writeln('  ', it^.k);

  writeln('Removing lowest 10 numbers');
  { NOTE: This will go wrong if more than 40 "random" numbers are equal,
    because these will only be stored once and after some deletions the
    tree will be empty and the program crashes. }
  for i := 1 to 10 do begin
    intTree.Delete(intTree.First)
  end;
  
  writeln('Printing remaining numbers in order:');
  it := intTree.First;
  while it <> intTree.Last do begin
    writeln('  ', it^.k);
    TMyRBTree.RBInc(it);
  end;
  writeln('  ', it^.k);
  
  writeln('Destroying tree');
  intTree.Destroy;
end.

