program Hashing;

type
{----------------------------------------------------------------------------}
   PClen = ^Clen; { clen tridene struktury }
   Clen = record
           {
             struktura recordu ... }
             klic : integer;
            {
             ...
             ...
             ...
            }
          end;
{----------------------------------------------------------------------------}
   PTabTyp = ^TabTyp;
   TabTyp = record
             pravy      : PTabTyp;
             zaznam     : PClen
            end;
{----------------------------------------------------------------------------}
   PHash = ^Hash;
   Hash = object
           velikost_tabulky : integer;
           vlozeno : integer;
           prehesuj_pri : byte;
           constructor Init( ivelikost_tabulky : integer;iprehesuj_pri : byte );
           procedure Zatrid( Zaznam : PClen ); virtual;
           procedure Vyndej( Min : PClen ); virtual;
           procedure Smaz( Co : PClen ); virtual;
           function Zaplneno : byte; virtual; { vraci v procentech 0 - 100 ) }
           procedure Prehesuj( velikost : integer ); virtual;
           destructor Done;
          end;
{----------------------------------------------------------------------------}
var tabulka : array [ 1..8000 ] of TabTyp;
{----------------------------------------------------------------------------}
{ metody : }
{----------------------------------------------------------------------------}
constructor Hash.Init( ivelikost_tabulky : integer;iprehesuj_pri : byte );
 begin
  velikost_tabulky := ivelikost_tabulky;
  prehesuj_pri := iprehesuj_pri;
  vlozeno := 0;
 end;
{----------------------------------------------------------------------------}
procedure Hash.Zatrid( Zaznam : PClen );
var klic        : integer;
    pomoc,uzel  : PTabTyp;
 begin
  { zvolil jsem hasovaci funkci index = f(klic) = klic mod sirka_tabulky }
  klic :=  Zaznam^.Klic mod velikost_tabulky;
  inc( vlozeno );

  if tabulka[ klic ].zaznam = nil then
   begin
    tabulka[ klic ].zaznam := Zaznam;
    tabulka[ klic ].pravy := nil;
   end
  else
   begin
    { musim najit misto kam zapojit - tridim od nejmensiho k nejvetsimu }
    if ( Zaznam^.klic < tabulka[ klic ].zaznam^.klic) then
     begin
      { vse posunout }
      new( pomoc );
      pomoc^ := tabulka[ klic ];
      tabulka[ klic ].zaznam := Zaznam;
      tabulka[ klic ].pravy := pomoc;
     end
    else
     begin
      pomoc := tabulka[ klic ].pravy;
      while ( pomoc^.pravy <> nil ) and
            ( Zaznam^.klic < pomoc^.zaznam^.klic ) do
        pomoc := pomoc^.pravy;{ a jsem na konci seznamku }

      new( uzel );
      uzel^ := pomoc^;
      pomoc^.pravy := uzel;
      pomoc^.zaznam := Zaznam;
     end
   end;

  if Zaplneno > prehesuj_pri then Prehesuj( ( velikost_tabulky + 1000 ) );

 end;
{----------------------------------------------------------------------------}
procedure Hash.Vyndej( Min : PClen );
 begin
  { najde nejmensi prvek a vrati na nej pointer }
 end;
{----------------------------------------------------------------------------}
procedure Hash.Smaz( Co : PClen ); virtual;
var index : integer;
 begin
  { vymaze prvek z tabulky na nejz mame pointer }
 end;
{----------------------------------------------------------------------------}
function Hash.Zaplneno : byte;
var pomoc : real;
 begin
  inc( vlozeno );
  Zaplneno := round(( vlozeno / velikost_tabulky ) * 100 );
 end;
{----------------------------------------------------------------------------}
procedure Hash.Prehesuj( velikost : integer );
 begin
  { prehesuje stavajici tabulku do vetsi tabulky }
 end;
{----------------------------------------------------------------------------}
destructor Hash.Done;
 begin
  { zruseni objektu }
 end;
{----------------------------------------------------------------------------}
begin

end.