46 lines
1.6 KiB
TypeScript
46 lines
1.6 KiB
TypeScript
/** FIFO with amortized O(1) removal, without Array.shift on each item. */
|
|
export function createDeque<T>() {
|
|
let items: T[] = [], head = 0;
|
|
return {
|
|
get size() { return items.length - head; },
|
|
push(value: T) { items.push(value); },
|
|
peek(): T | undefined { return items[head]; },
|
|
pop(): T | undefined {
|
|
if (head === items.length) return undefined;
|
|
const value = items[head++];
|
|
if (head > 1024 && head * 2 >= items.length) { items = items.slice(head); head = 0; }
|
|
return value;
|
|
},
|
|
clear() { items = []; head = 0; },
|
|
values() { return items.slice(head); },
|
|
};
|
|
}
|
|
export function createMinHeap<T>(compare: (left: T, right: T) => number) {
|
|
const items: T[] = [];
|
|
return {
|
|
get size() { return items.length; },
|
|
peek(): T | undefined { return items[0]; },
|
|
push(value: T) {
|
|
let index = items.length; items.push(value);
|
|
while (index > 0) { const parent = (index - 1) >> 1; if (compare(items[parent], value) <= 0) break; items[index] = items[parent]; index = parent; }
|
|
items[index] = value;
|
|
},
|
|
pop(): T | undefined {
|
|
if (!items.length) return undefined;
|
|
const first = items[0], last = items.pop()!;
|
|
if (items.length) {
|
|
let index = 0;
|
|
while (index * 2 + 1 < items.length) {
|
|
let child = index * 2 + 1;
|
|
if (child + 1 < items.length && compare(items[child + 1], items[child]) < 0) child++;
|
|
if (compare(last, items[child]) <= 0) break;
|
|
items[index] = items[child]; index = child;
|
|
}
|
|
items[index] = last;
|
|
}
|
|
return first;
|
|
},
|
|
clear() { items.length = 0; },
|
|
};
|
|
}
|