spica
Version:
Supervisor, Coroutine, Channel, select, AtomicPromise, Cancellation, Cache, List, Queue, Stack, and some utils.
234 lines (203 loc) • 7.55 kB
text/typescript
import { Heap } from './heap';
import { xorshift } from './random';
describe('Unit: lib/heap', () => {
describe('Heap', () => {
function inspect<T>(heap: Heap<T>) {
return Object.values(heap['array']);
}
it('insert/extract', () => {
const heap = new Heap<number>();
assert(heap.extract() === undefined);
assert.deepStrictEqual(heap.insert(1, 1), { index: 1, order: 1, value: 1 });
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 1, value: 1 },
]);
assert.deepStrictEqual(heap.insert(2, 2), { index: 1, order: 2, value: 2 });
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 2, value: 2 },
{ index: 2, order: 1, value: 1 },
]);
assert.deepStrictEqual(heap.insert(3, 3), { index: 1, order: 3, value: 3 });
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 3, value: 3 },
{ index: 2, order: 1, value: 1 },
{ index: 3, order: 2, value: 2 },
]);
assert.deepStrictEqual(heap.insert(0, 0), { index: 4, order: 0, value: 0 });
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 3, value: 3 },
{ index: 2, order: 1, value: 1 },
{ index: 3, order: 2, value: 2 },
{ index: 4, order: 0, value: 0 },
]);
assert.deepStrictEqual(heap.insert(11, 11), { index: 1, order: 11, value: 11 });
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 11, value: 11 },
{ index: 2, order: 3, value: 3 },
{ index: 3, order: 2, value: 2 },
{ index: 4, order: 0, value: 0 },
{ index: 5, order: 1, value: 1 },
]);
assert.deepStrictEqual(heap.insert(10, 10), { index: 3, order: 10, value: 10 });
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 11, value: 11 },
{ index: 2, order: 3, value: 3 },
{ index: 3, order: 10, value: 10 },
{ index: 4, order: 0, value: 0 },
{ index: 5, order: 1, value: 1 },
{ index: 6, order: 2, value: 2 },
]);
assert(heap.extract() === 11);
assert(heap.extract() === 10);
assert(heap.extract() === 3);
assert(heap.extract() === 2);
assert(heap.extract() === 1);
assert(heap.extract() === 0);
});
it('replace', () => {
const heap = new Heap<number>();
assert(heap.replace(0, 0) === undefined);
assert(heap.length === 1);
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 0, value: 0 },
]);
assert(heap.replace(1, 1) === 0);
assert(heap.length === 1);
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 1, value: 1 },
]);
assert.deepStrictEqual(heap.insert(2, 2), { index: 1, order: 2, value: 2 });
assert.deepStrictEqual(heap.insert(3, 3), { index: 1, order: 3, value: 3 });
assert.deepStrictEqual(heap.insert(4, 4), { index: 1, order: 4, value: 4 });
assert.deepStrictEqual(heap.insert(5, 5), { index: 1, order: 5, value: 5 });
assert.deepStrictEqual(heap.insert(6, 6), { index: 1, order: 6, value: 6 });
assert.deepStrictEqual(heap.insert(7, 7), { index: 1, order: 7, value: 7 });
assert(heap.length === 7);
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 7, value: 7 },
{ index: 2, order: 4, value: 4 },
{ index: 3, order: 6, value: 6 },
{ index: 4, order: 1, value: 1 },
{ index: 5, order: 3, value: 3 },
{ index: 6, order: 2, value: 2 },
{ index: 7, order: 5, value: 5 },
]);
assert(heap.replace(0, 0) === 7);
assert(heap.length === 7);
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 6, value: 6 },
{ index: 2, order: 4, value: 4 },
{ index: 3, order: 5, value: 5 },
{ index: 4, order: 1, value: 1 },
{ index: 5, order: 3, value: 3 },
{ index: 6, order: 2, value: 2 },
{ index: 7, order: 0, value: 0 },
]);
});
it('delete', () => {
const heap = new Heap<number>();
assert(heap.extract() === undefined);
const nodes = [
heap.insert(1, 1),
heap.insert(2, 2),
heap.insert(3, 3),
heap.insert(4, 4),
];
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 4, value: 4 },
{ index: 2, order: 3, value: 3 },
{ index: 3, order: 2, value: 2 },
{ index: 4, order: 1, value: 1 },
]);
assert.deepStrictEqual(heap.delete(nodes[0]), 1);
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 4, value: 4 },
{ index: 2, order: 3, value: 3 },
{ index: 3, order: 2, value: 2 },
undefined,
]);
assert.deepStrictEqual(heap.delete(nodes[2]), 3);
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 4, value: 4 },
{ index: 2, order: 2, value: 2 },
undefined,
undefined,
]);
});
it('stable', () => {
const heap = new Heap<number>(undefined, { stable: true });
heap.insert(1, 1);
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 1, value: 1 },
]);
heap.insert(3, 3);
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 3, value: 3 },
{ index: 2, order: 1, value: 1 },
]);
heap.insert(2.1, 2);
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 3, value: 3 },
{ index: 2, order: 1, value: 1 },
{ index: 3, order: 2, value: 2.1 },
]);
heap.insert(2.2, 2);
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 3, value: 3 },
{ index: 2, order: 2, value: 2.2 },
{ index: 3, order: 2, value: 2.1 },
{ index: 4, order: 1, value: 1 },
]);
assert(heap.extract() === 3);
assert(heap.extract() === 2.1);
assert(heap.extract() === 2.2);
assert(heap.extract() === 1);
heap.clear();
const nodes = [
heap.insert(0, 0),
heap.insert(1, 0),
heap.insert(2, 0),
heap.insert(3, 0),
heap.insert(4, 0),
heap.insert(5, 0),
heap.insert(6, 0),
];
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 0, value: 0 },
{ index: 2, order: 0, value: 1 },
{ index: 3, order: 0, value: 2 },
{ index: 4, order: 0, value: 3 },
{ index: 5, order: 0, value: 4 },
{ index: 6, order: 0, value: 5 },
{ index: 7, order: 0, value: 6 },
]);
heap.update(nodes[1], 0);
assert.deepStrictEqual(inspect(heap), [
{ index: 1, order: 0, value: 0 },
{ index: 2, order: 0, value: 1 },
{ index: 3, order: 0, value: 2 },
{ index: 4, order: 0, value: 3 },
{ index: 5, order: 0, value: 4 },
{ index: 6, order: 0, value: 5 },
{ index: 7, order: 0, value: 6 },
]);
});
for (let i = 0; i < 20; ++i) it(`verify ${i}`, function () {
const heap = new Heap<number>();
const size = 1e4;
const random = xorshift.random(3 ** i);
for (let i = 0; i < size; ++i) {
const ord = random() * 1e6 | 0;
heap.insert(ord, ord);
}
assert(heap.length === size);
for (let i = 0, o = Infinity; i < size; ++i) {
const node = heap.peek()!;
assert(node.order <= o);
o = node.order;
heap.delete(node);
}
assert(heap.length === 0);
});
});
});