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