Files
sdk/pkg/kernel/lib/src/heap.dart
T
Johnni Winther 286702df6b [kernel] Migrate tests
Change-Id: If426fc15f7bce54b51eaac3354061684cd5b0e17
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207129
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
2021-07-27 12:35:37 +00:00

63 lines
1.6 KiB
Dart

// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/// Basic implementation of a heap, with O(log n) insertion and removal.
abstract class Heap<T> {
final _items = <T>[];
bool get isEmpty => _items.isEmpty;
bool get isNotEmpty => _items.isNotEmpty;
void add(T item) {
int index = _items.length;
_items.add(item);
while (index > 0) {
T parent = _items[_parentIndex(index)];
if (sortsBefore(parent, item)) break;
_items[index] = parent;
index = _parentIndex(index);
}
_items[index] = item;
}
T remove() {
T removed = _items[0];
T orphan = _items.removeLast();
if (_items.isNotEmpty) _reInsert(orphan);
return removed;
}
/// Client should use a derived class to specify the sort order.
bool sortsBefore(T a, T b);
int _firstChildIndex(int index) {
return (index << 1) + 1;
}
int _parentIndex(int index) {
return (index - 1) >> 1;
}
void _reInsert(T item) {
int index = 0;
while (true) {
int childIndex = _firstChildIndex(index);
if (childIndex >= _items.length) break;
T child = _items[childIndex];
if (childIndex + 1 < _items.length) {
T nextChild = _items[childIndex + 1];
if (sortsBefore(nextChild, child)) {
child = nextChild;
childIndex++;
}
}
if (sortsBefore(item, child)) break;
_items[index] = _items[childIndex];
index = childIndex;
}
_items[index] = item;
}
}