Contributor: SWAG SUPPORT TEAM        

{
> Does anyone have code(preferably TP) the implements AVL trees?
> I'm having trouble With the insertion part of it.  I'm writing a small
> parts inventory Program For work(although I'm not employed as a
> Programmer) and the AVL tree would be very fast For it.
}


Program avl;

Type
  nodeptr = ^node;
  node    = Record
    key   : Char;
    bal   : -1..+1; { bal = h(right) - h(left) }
    left,
    right : nodeptr
  end;

  tree = nodeptr;

Var
  t : tree;
  h : Boolean; { insert & delete parameter }


Procedure maketree(Var t : tree);
begin
  t := nil;
end;

Function member(k : Char; t : tree) : Boolean;
begin { member }
  if t = nil then
    member := False
  else
  if k = t^.key then
    member := True
  else
  if k < t^.key then
    member := member(k, t^.left)
  else
    member := member(k, t^.right);
end;

Procedure ll(Var t : tree);
Var
  p : tree;
begin
  p := t^.left;
  t^.left  := p^.right;
  p^.right := t;
  t := p;
end;

Procedure rr(Var t : tree);
Var
   p : tree;
begin
  p := t^.right;
  t^.right := p^.left;
  p^.left  := t;
  t := p;
end

Procedure lr(Var t : tree);
begin
  rr(t^.left);
  ll(t);
end;

Procedure rl(Var t : tree);
begin
  ll(t^.right);
  rr(t);
end;

Procedure insert(k : Char; Var t : tree; Var h : Boolean);

  Procedure balanceleft(Var t : tree; Var h : Boolean);
  begin
    Writeln('balance left');
    Case t^.bal of
      +1 :
        begin
          t^.bal := 0;
          h := False;
        end;
       0 : t^.bal := -1;
      -1 :
        begin { rebalance }
          if t^.left^.bal = -1 then
          begin { single ll rotation }
            Writeln('single ll rotation');
            ll(t);
            t^.right^.bal := 0;
          end
          else { t^.left^.bal  = +1 }
          begin  { double lr rotation }
            Writeln('double lr rotation');
            lr(t);
            if t^.bal = -1 then
              t^.right^.bal := +1
            else
              t^.right^.bal := 0;
            if t^.bal = +1 then
              t^.left^.bal := -1
            else
              t^.left^.bal := 0;
          end;
          t^.bal := 0;
          h := False;
        end;
    end;
  end;

  Procedure balanceright(Var t : tree; Var h : Boolean);
  begin
    Writeln('balance right');
    Case t^.bal of
      -1 :
        begin
          t^.bal := 0;
          h := False;
        end;
       0 : t^.bal := +1;
      +1 :
        begin { rebalance }
          if t^.right^.bal = +1 then
          begin { single rr rotation }
            Writeln('single rr rotation');
            rr(t);
            t^.left^.bal := 0
          end
          else { t^.right^.bal  = -1 }
          begin  { double rl rotation }
            Writeln('double rl rotation');
            rl(t);
            if t^.bal = -1 then
              t^.right^.bal := +1
            else
              t^.right^.bal := 0;
            if t^.bal = +1 then
              t^.left^.bal := -1
            else
              t^.left^.bal := 0;
          end;
          t^.bal := 0;
          h := False;
        end;
    end;
  end;

begin { insert }
  if t = nil then
  begin
    new(t);
    t^.key   := k;
    t^.bal   := 0;
    t^.left  := nil;
    t^.right := nil;
          h := True;
  end
  else
  if k < t^.key then
  begin
    insert(k, t^.left, h);
          if h then
      balanceleft(t, h);
  end
  else
  if k > t^.key then
  begin
    insert(k, t^.right, h);
    if h then
      balanceright(t, h);
  end;
end;

Procedure delete(k : Char; Var t : tree; Var h : Boolean);

  Procedure balanceleft(Var t : tree; Var h : Boolean);
  begin
    Writeln('balance left');
    Case t^.bal of
      -1 :
        begin
          t^.bal := 0;
          h := True;
        end;
       0 :
         begin
                 t^.bal := +1;
                 h := False;
               end;
      +1 :
        begin { rebalance }
          if t^.right^.bal >= 0 then
          begin
            Writeln('single rr rotation'); { single rr rotation }
                        if t^.right^.bal = 0 then
            begin
              rr(t);
                          t^.bal := -1;
                          h := False;
                        end
                        else
            begin
              rr(t);
                          t^.left^.bal := 0;
                          t^.bal := 0;
                          h := True;
                        end;
          end
          else { t^.right^.bal  = -1 }
          begin
                        Writeln('double rl rotation');
                   rl(t);
                        t^.left^.bal := 0;
            t^.right^.bal := 0;
                        h := True;
                      end;
        end;
    end;
  end;

  Procedure balanceright(Var t : tree; Var h : Boolean);
  begin
    Writeln('balance right');
    Case t^.bal of
      +1 :
        begin
          t^.bal := 0;
          h := True;
        end;
       0 :
         begin
                 t^.bal := -1;
                 h := False;
               end;
      -1 :
        begin { rebalance }
          if t^.left^.bal <= 0 then
          begin { single ll rotation }
            Writeln('single ll rotation');
                        if t^.left^.bal = 0 then
            begin
              ll(t);
                          t^.bal := +1;
                          h := False;
                        end
                        else
            begin
              ll(t);
                          t^.left^.bal := 0;
                          t^.bal := 0;
                          h := True;
                        end;
          end
          else { t^.left^.bal  = +1 }
          begin  { double lr rotation }
            Writeln('double lr rotation');
            lr(t);
                        t^.left^.bal := 0;
                        t^.right^.bal := 0;
                        h := True;
          end;
        end;
    end;
  end;

  Function deletemin(Var t : tree; Var h : Boolean) : Char;
  begin { deletemin }
    if t^.left = nil then
    begin
      deletemin := t^.key;
      t := t^.right;
            h := True;
    end
    else
    begin
      deletemin := deletemin(t^.left, h);
            if h then
        balanceleft(t, h);
    end;
  end;

begin { delete }
  if t <> nil then
  begin
    if k < t^.key then
    begin
      delete(k, t^.left, h);
            if h then
        balanceleft(t, h);
    end
    else
    if k > t^.key then
    begin
      delete(k, t^.right, h);
            if h then
        balanceright(t, h);
    end
    else
    if (t^.left = nil) and (t^.right = nil) then
    begin
      t := nil;
            h := True;
    end
    else
    if t^.left = nil then
    begin
      t := t^.right;
            h := True;
    end
    else
    if t^.right = nil then
    begin
      t := t^.left;
            h := True;
    end
    else
    begin
      t^.key := deletemin(t^.right, h);
            if h then
              balanceright(t, h);
    end;
  end;
end;

begin
end.