1 (* Copyright (C) DooM 2D:Forever Developers
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 {$INCLUDE a_modes.inc}
24 // WARNING! don't put structures into heap, use ponters or ids!
25 generic TBinaryHeapBase
<ITP
> = class(TObject
)
28 TBinaryHeapLessFn
= function (a
, b
: ITP
): Boolean;
33 lessfn
: TBinaryHeapLessFn
;
36 procedure heapify (root
: Integer);
39 constructor Create (alessfn
: TBinaryHeapLessFn
);
40 destructor Destroy (); override;
44 procedure insert (val
: ITP
);
46 function front (): ITP
;
47 procedure popFront ();
49 property count
: Integer read elemUsed
;
54 TBinaryHeapObj
= specialize TBinaryHeapBase
<TObject
>;
55 TBinaryHeapInt
= specialize TBinaryHeapBase
<Integer>;
58 function binHeapNewIntLess (): TBinaryHeapInt
;
59 function binHeapNewIntGreat (): TBinaryHeapInt
;
68 // ////////////////////////////////////////////////////////////////////////// //
69 function intLess (a
, b
: Integer): Boolean; begin result
:= (a
< b
); end;
70 function intGreat (a
, b
: Integer): Boolean; begin result
:= (a
> b
); end;
73 function binHeapNewIntLess (): TBinaryHeapInt
; begin result
:= TBinaryHeapInt
.Create(@intLess
); end;
74 function binHeapNewIntGreat (): TBinaryHeapInt
; begin result
:= TBinaryHeapInt
.Create(@intGreat
); end;
77 // ////////////////////////////////////////////////////////////////////////// //
78 constructor TBinaryHeapBase
.Create (alessfn
: TBinaryHeapLessFn
);
80 if not assigned(alessfn
) then raise Exception
.Create('wutafuck?!');
82 SetLength(elem
, 128); // 'cause why not?
87 destructor TBinaryHeapBase
.Destroy ();
94 procedure TBinaryHeapBase
.clear ();
100 procedure TBinaryHeapBase
.heapify (root
: Integer);
102 smallest
, right
: Integer;
107 smallest
:= 2*root
+1; // left child
108 if (smallest
>= elemUsed
) then break
; // anyway
109 right
:= smallest
+1; // right child
110 if not lessfn(elem
[smallest
], elem
[root
]) then smallest
:= root
;
111 if (right
< elemUsed
) and (lessfn(elem
[right
], elem
[smallest
])) then smallest
:= right
;
112 if (smallest
= root
) then break
;
115 elem
[root
] := elem
[smallest
];
116 elem
[smallest
] := tmp
;
122 procedure TBinaryHeapBase
.insert (val
: ITP
);
126 //if (val = nil) then exit;
129 if (i
= Length(elem
)) then
131 if (i
<= 65536) then par
:= i
*2 else par
:= i
+65536; // arbitrary numbers
132 SetLength(elem
, par
);
139 par
:= (i
-1) div 2; // parent
140 if not lessfn(val
, elem
[par
]) then break
;
141 elem
[i
] := elem
[par
];
147 function TBinaryHeapBase
.front (): ITP
;
149 if elemUsed
> 0 then result
:= elem
[0] else result
:= Default(ITP
);
153 procedure TBinaryHeapBase
.popFront ();
155 if (elemUsed
> 0) then
158 elem
[0] := elem
[elemUsed
];