Implemented the "Heap" data structure
parent
637cb053c4
commit
576a42b670
|
|
@ -0,0 +1,83 @@
|
||||||
|
class Heap<T> {
|
||||||
|
|
||||||
|
final int Function(T) getPriority;
|
||||||
|
List<(T, int)> _items;
|
||||||
|
|
||||||
|
Heap({
|
||||||
|
required this.getPriority
|
||||||
|
}): _items = [];
|
||||||
|
|
||||||
|
factory Heap.fromItems(
|
||||||
|
List<T> items,
|
||||||
|
{
|
||||||
|
required int Function(T) getPriority,
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Heap<T> heap = Heap(getPriority: getPriority);
|
||||||
|
for (final T item in items) {
|
||||||
|
heap.add(item);
|
||||||
|
}
|
||||||
|
return heap;
|
||||||
|
}
|
||||||
|
|
||||||
|
T get first => _items.first.$1;
|
||||||
|
|
||||||
|
T? get firstOrNull => _items.firstOrNull?.$1;
|
||||||
|
|
||||||
|
int get length => _items.length;
|
||||||
|
|
||||||
|
bool get isEmpty => _items.isEmpty;
|
||||||
|
|
||||||
|
bool get isNotEmpty => _items.isNotEmpty;
|
||||||
|
|
||||||
|
void add(T item) {
|
||||||
|
final (T, int) heapItem = (item, getPriority(item));
|
||||||
|
final int thisKey = heapItem.$2;
|
||||||
|
int i = _items.length;
|
||||||
|
_items.add(heapItem);
|
||||||
|
while (i > 0 && _items[(i-1) ~/ 2].$2 > thisKey) {
|
||||||
|
_items[i] = _items[(i-1) ~/ 2];
|
||||||
|
i = (i-1)~/2;
|
||||||
|
}
|
||||||
|
_items[i] = heapItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
T removeFirst() {
|
||||||
|
if (_items.isEmpty) {
|
||||||
|
throw StateError("No element");
|
||||||
|
}
|
||||||
|
final T firstItem = _items[0].$1;
|
||||||
|
if (_items.length < 2) {
|
||||||
|
_items.length--;
|
||||||
|
return firstItem;
|
||||||
|
}
|
||||||
|
final (T, int) itemToMove = _items.last;
|
||||||
|
_items[0] = itemToMove;
|
||||||
|
_items.length--;
|
||||||
|
int i = 0;
|
||||||
|
int leftIndex, rightIndex;
|
||||||
|
bool stop = false;
|
||||||
|
while (!stop) {
|
||||||
|
rightIndex = (i+1) << 1;
|
||||||
|
leftIndex = rightIndex-1;
|
||||||
|
if (leftIndex < _items.length && itemToMove.$2 > _items[leftIndex].$2) {
|
||||||
|
if (rightIndex < _items.length && _items[leftIndex].$2 > _items[rightIndex].$2) {
|
||||||
|
_items[i] = _items[rightIndex];
|
||||||
|
_items[rightIndex] = itemToMove;
|
||||||
|
i = rightIndex;
|
||||||
|
} else {
|
||||||
|
_items[i] = _items[leftIndex];
|
||||||
|
_items[leftIndex] = itemToMove;
|
||||||
|
i = leftIndex;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stop = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return firstItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _items.map(((T, int) item) => item.$1).toString();
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue