286702df6b
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>
63 lines
1.6 KiB
Dart
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;
|
|
}
|
|
}
|