Changeset 447 for trunk/IPQ.pas
- Timestamp:
- May 19, 2022, 10:39:34 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/IPQ.pas
r442 r447 1 1 { binary heap priority queue 2 code contributed by Rassim Eminli }2 Code contributed by Rassim Eminli } 3 3 4 4 {$INCLUDE Switches.inc} … … 8 8 9 9 type 10 TIntegerArray = array [0 .. $40000000 div sizeof(integer)] of integer;10 TIntegerArray = array [0 .. $40000000 div SizeOf(Integer)] of Integer; 11 11 PIntegerArray = ^TIntegerArray; 12 12 13 13 TheapItem = record 14 Item: integer;15 Value: integer;14 Item: Integer; 15 Value: Integer; 16 16 end; 17 17 18 TItemArray = array [0 .. $40000000 div sizeof(TheapItem)] of TheapItem;18 TItemArray = array [0 .. $40000000 div SizeOf(TheapItem)] of TheapItem; 19 19 PItemArray = ^TItemArray; 20 20 21 21 TIPQ = class 22 constructor Create( max: integer);22 constructor Create(Max: Integer); 23 23 destructor Destroy; override; 24 24 procedure Empty; 25 function Put(Item, Value: integer): boolean;26 function TestPut(Item, Value: integer): boolean;27 function Get(var Item, Value: integer): boolean;25 function Put(Item, Value: Integer): Boolean; 26 function TestPut(Item, Value: Integer): Boolean; 27 function Get(var Item, Value: Integer): Boolean; 28 28 private 29 29 // n - is the size of the heap. 30 30 // fmax - is the max size of the heap. 31 n, fmax: integer;31 N, fmax: Integer; 32 32 33 33 // bh - stores (Value, Item) pairs of the heap. … … 39 39 implementation 40 40 41 constructor TIPQ.Create( max: integer);41 constructor TIPQ.Create(Max: Integer); 42 42 begin 43 43 inherited Create; 44 fmax := max;45 GetMem(bh, fmax * sizeof(TheapItem));46 GetMem(Ix, fmax * sizeof(integer));47 n:= -1;44 fmax := Max; 45 GetMem(bh, fmax * SizeOf(TheapItem)); 46 GetMem(Ix, fmax * SizeOf(Integer)); 47 N := -1; 48 48 Empty; 49 49 end; … … 58 58 procedure TIPQ.Empty; 59 59 begin 60 if n<> 0 then60 if N <> 0 then 61 61 begin 62 FillChar(Ix^, fmax * sizeof(integer), 255);63 n:= 0;62 FillChar(Ix^, fmax * SizeOf(Integer), 255); 63 N := 0; 64 64 end; 65 65 end; 66 66 67 67 // Parent(i) = (i-1)/2. 68 function TIPQ.Put(Item, Value: integer): boolean; // O(lg(n))68 function TIPQ.Put(Item, Value: Integer): Boolean; // O(lg(n)) 69 69 var 70 i, j: integer;70 I, J: Integer; 71 71 lbh: PItemArray; 72 72 lIx: PIntegerArray; … … 74 74 lIx := Ix; 75 75 lbh := bh; 76 i:= lIx[Item];77 if i>= 0 then76 I := lIx[Item]; 77 if I >= 0 then 78 78 begin 79 if lbh[ i].Value <= Value then79 if lbh[I].Value <= Value then 80 80 begin 81 result := False;82 exit;81 Result := False; 82 Exit; 83 83 end; 84 84 end 85 85 else 86 86 begin 87 i := n;88 Inc( n);87 I := N; 88 Inc(N); 89 89 end; 90 90 91 while i> 0 do91 while I > 0 do 92 92 begin 93 j := (i- 1) shr 1; // Parent(i) = (i-1)/294 if Value >= lbh[ j].Value then95 break;96 lbh[ i] := lbh[j];97 lIx[lbh[ i].Item] := i;98 i := j;93 J := (I - 1) shr 1; // Parent(i) = (i-1)/2 94 if Value >= lbh[J].Value then 95 Break; 96 lbh[I] := lbh[J]; 97 lIx[lbh[I].Item] := I; 98 I := J; 99 99 end; 100 100 // Insert the new Item at the insertion point found. 101 lbh[ i].Value := Value;102 lbh[ i].Item := Item;103 lIx[lbh[ i].Item] := i;104 result := True;101 lbh[I].Value := Value; 102 lbh[I].Item := Item; 103 lIx[lbh[I].Item] := I; 104 Result := True; 105 105 end; 106 106 107 function TIPQ.TestPut(Item, Value: integer): boolean;107 function TIPQ.TestPut(Item, Value: Integer): Boolean; 108 108 var 109 i: integer;109 I: Integer; 110 110 begin 111 i:= Ix[Item];112 result := (i < 0) or (bh[i].Value > Value);111 I := Ix[Item]; 112 Result := (I < 0) or (bh[I].Value > Value); 113 113 end; 114 114 115 115 // Left(i) = 2*i+1. 116 116 // Right(i) = 2*i+2 => Left(i)+1 117 function TIPQ.Get(var Item, Value: integer): boolean; // O(lg(n))117 function TIPQ.Get(var Item, Value: Integer): Boolean; // O(lg(n)) 118 118 var 119 i, j: integer;120 last: TheapItem;119 I, J: Integer; 120 Last: TheapItem; 121 121 lbh: PItemArray; 122 122 begin 123 if n= 0 then123 if N = 0 then 124 124 begin 125 result := False;126 exit;125 Result := False; 126 Exit; 127 127 end; 128 128 … … 133 133 Ix[Item] := -1; 134 134 135 dec(n);136 if n> 0 then135 Dec(N); 136 if N > 0 then 137 137 begin 138 last := lbh[n];139 i:= 0;140 j:= 1;141 while j < ndo138 Last := lbh[N]; 139 I := 0; 140 J := 1; 141 while J < N do 142 142 begin 143 143 // Right(i) = Left(i)+1 144 if ( j < n - 1) and (lbh[j].Value > lbh[j+ 1].Value) then145 Inc( j);146 if last.Value <= lbh[j].Value then147 break;144 if (J < N - 1) and (lbh[J].Value > lbh[J + 1].Value) then 145 Inc(J); 146 if Last.Value <= lbh[J].Value then 147 Break; 148 148 149 lbh[ i] := lbh[j];150 Ix[lbh[ i].Item] := i;151 i := j;152 j := jshl 1 + 1; // Left(j) = 2*j+1149 lbh[I] := lbh[J]; 150 Ix[lbh[I].Item] := I; 151 I := J; 152 J := J shl 1 + 1; // Left(j) = 2*j+1 153 153 end; 154 154 155 155 // Insert the root in the correct place in the heap. 156 lbh[ i] := last;157 Ix[ last.Item] := i;156 lbh[I] := Last; 157 Ix[Last.Item] := I; 158 158 end; 159 result := True;159 Result := True; 160 160 end; 161 161
Note:
See TracChangeset
for help on using the changeset viewer.