mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
[heap, priority queue] Redesigned tested pass
This commit is contained in:
parent
5fcd9fe5e0
commit
c6177ffeb9
|
@ -21,34 +21,42 @@ describe('Heap Operation Test', () => {
|
|||
});
|
||||
|
||||
it('should object heap work well', function () {
|
||||
const minHeap = new MinHeap<{a: string}>();
|
||||
minHeap.add(1, {a: 'a1'});
|
||||
minHeap.add(6, {a: 'a6'});
|
||||
minHeap.add(2, {a: 'a2'});
|
||||
minHeap.add(0, {a: 'a0'});
|
||||
const minHeap = new MinHeap<{a: string; key: number}>((a, b) => a.key - b.key);
|
||||
minHeap.add({key: 1, a: 'a1'});
|
||||
minHeap.add({key: 6, a: 'a6'});
|
||||
minHeap.add({key: 2, a: 'a2'});
|
||||
minHeap.add({key: 0, a: 'a0'});
|
||||
|
||||
expect(minHeap.peek()).toEqual({a: 'a0'});
|
||||
expect(minHeap.toArray()).toEqual([{a: 'a0'}, {a: 'a1'}, {a: 'a2'}, {a: 'a6'}]);
|
||||
expect(minHeap.peek()).toEqual({a: 'a0', key: 0});
|
||||
console.log('---', minHeap.toArray());
|
||||
expect(minHeap.toArray().map(item => ({a: item.a}))).toEqual([{a: 'a0'}, {a: 'a1'}, {a: 'a2'}, {a: 'a6'}]);
|
||||
let i = 0;
|
||||
const expectPolled = [{a: 'a0'}, {a: 'a1'}, {a: 'a2'}, {a: 'a6'}];
|
||||
while (minHeap.size > 0) {
|
||||
expect(minHeap.poll()).toEqual(expectPolled[i]);
|
||||
expect({a: minHeap.poll()?.a}).toEqual(expectPolled[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
const maxHeap = new MaxHeap<{a: string}>();
|
||||
maxHeap.add(1, {a: 'a1'});
|
||||
maxHeap.add(6, {a: 'a6'});
|
||||
maxHeap.add(5, {a: 'a5'});
|
||||
maxHeap.add(2, {a: 'a2'});
|
||||
maxHeap.add(0, {a: 'a0'});
|
||||
maxHeap.add(9, {a: 'a9'});
|
||||
expect(maxHeap.peek()).toEqual({a: 'a9'});
|
||||
expect(maxHeap.toArray()).toEqual([{a: 'a9'}, {a: 'a2'}, {a: 'a6'}, {a: 'a1'}, {a: 'a0'}, {a: 'a5'}]);
|
||||
const maxHeap = new MaxHeap<{key: number; a: string}>((a, b) => b.key - a.key);
|
||||
maxHeap.add({key: 1, a: 'a1'});
|
||||
maxHeap.add({key: 6, a: 'a6'});
|
||||
maxHeap.add({key: 5, a: 'a5'});
|
||||
maxHeap.add({key: 2, a: 'a2'});
|
||||
maxHeap.add({key: 0, a: 'a0'});
|
||||
maxHeap.add({key: 9, a: 'a9'});
|
||||
expect(maxHeap.peek()).toEqual({a: 'a9', key: 9});
|
||||
expect(maxHeap.toArray().map(item => ({a: item.a}))).toEqual([
|
||||
{a: 'a9'},
|
||||
{a: 'a2'},
|
||||
{a: 'a6'},
|
||||
{a: 'a1'},
|
||||
{a: 'a0'},
|
||||
{a: 'a5'}
|
||||
]);
|
||||
const maxExpectPolled = [{a: 'a9'}, {a: 'a6'}, {a: 'a5'}, {a: 'a2'}, {a: 'a1'}, {a: 'a0'}];
|
||||
let maxI = 0;
|
||||
while (maxHeap.size > 0) {
|
||||
expect(maxHeap.poll()).toEqual(maxExpectPolled[maxI]);
|
||||
expect({a: maxHeap.poll()?.a}).toEqual(maxExpectPolled[maxI]);
|
||||
maxI++;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,44 +1,52 @@
|
|||
import {HeapItem, MaxHeap} from '../../../../src';
|
||||
import {CompareFunction, MaxHeap} from '../../../../src';
|
||||
|
||||
describe('MaxHeap Operation Test', () => {
|
||||
it('should object Max Heap operations be proper', function () {
|
||||
const maxHeap = new MaxHeap<{keyA: string}>();
|
||||
const myObj1 = {keyA: 'a1'},
|
||||
myObj6 = {keyA: 'a6'},
|
||||
myObj5 = {keyA: 'a5'},
|
||||
myObj2 = {keyA: 'a2'},
|
||||
myObj0 = {keyA: 'a0'},
|
||||
myObj9 = {keyA: 'a9'};
|
||||
maxHeap.add(1, myObj1);
|
||||
expect(maxHeap.has(myObj1)).toBe(true);
|
||||
expect(maxHeap.has(myObj9)).toBe(false);
|
||||
maxHeap.add(6, myObj6);
|
||||
expect(maxHeap.has(myObj6)).toBe(true);
|
||||
maxHeap.add(5, myObj5);
|
||||
expect(maxHeap.has(myObj5)).toBe(true);
|
||||
maxHeap.add(2, myObj2);
|
||||
expect(maxHeap.has(myObj2)).toBe(true);
|
||||
expect(maxHeap.has(myObj6)).toBe(true);
|
||||
maxHeap.add(0, myObj0);
|
||||
expect(maxHeap.has(myObj0)).toBe(true);
|
||||
expect(maxHeap.has(myObj9)).toBe(false);
|
||||
maxHeap.add(9, myObj9);
|
||||
expect(maxHeap.has(myObj9)).toBe(true);
|
||||
describe('MaxHeap', () => {
|
||||
const numberComparator: CompareFunction<number> = (a, b) => b - a;
|
||||
let maxHeap: MaxHeap<number>;
|
||||
|
||||
const peek9 = maxHeap.peek(true);
|
||||
peek9 && peek9.val && expect(peek9.val.keyA).toBe('a9');
|
||||
beforeEach(() => {
|
||||
maxHeap = new MaxHeap(numberComparator);
|
||||
});
|
||||
|
||||
const heapToArr = maxHeap.toArray(true);
|
||||
expect(heapToArr.map(item => item?.val?.keyA)).toEqual(['a9', 'a2', 'a6', 'a1', 'a0', 'a5']);
|
||||
test('add and poll elements in descending order', () => {
|
||||
maxHeap.add(3);
|
||||
maxHeap.add(1);
|
||||
maxHeap.add(4);
|
||||
maxHeap.add(2);
|
||||
|
||||
const values = ['a9', 'a6', 'a5', 'a2', 'a1', 'a0'];
|
||||
let i = 0;
|
||||
while (maxHeap.size > 0) {
|
||||
const polled = maxHeap.poll(true);
|
||||
expect(polled).toBeInstanceOf(HeapItem);
|
||||
polled && expect(polled.val).toHaveProperty('keyA');
|
||||
polled && polled.val && expect(polled.val.keyA).toBe(values[i]);
|
||||
i++;
|
||||
}
|
||||
expect(maxHeap.poll()).toBe(4);
|
||||
expect(maxHeap.poll()).toBe(3);
|
||||
expect(maxHeap.poll()).toBe(2);
|
||||
expect(maxHeap.poll()).toBe(1);
|
||||
});
|
||||
|
||||
test('peek at the top element without removing it', () => {
|
||||
maxHeap.add(3);
|
||||
maxHeap.add(1);
|
||||
maxHeap.add(4);
|
||||
maxHeap.add(2);
|
||||
|
||||
expect(maxHeap.peek()).toBe(4);
|
||||
expect(maxHeap.size).toBe(4);
|
||||
});
|
||||
|
||||
test('sort elements in descending order', () => {
|
||||
maxHeap.add(3);
|
||||
maxHeap.add(1);
|
||||
maxHeap.add(4);
|
||||
maxHeap.add(2);
|
||||
|
||||
const sortedArray = maxHeap.sort();
|
||||
expect(sortedArray).toEqual([4, 3, 2, 1]);
|
||||
});
|
||||
|
||||
test('check if the heap is empty', () => {
|
||||
expect(maxHeap.isEmpty()).toBe(true);
|
||||
|
||||
maxHeap.add(5);
|
||||
expect(maxHeap.isEmpty()).toBe(false);
|
||||
|
||||
maxHeap.poll();
|
||||
expect(maxHeap.isEmpty()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,82 +1,52 @@
|
|||
import {HeapItem, MinHeap} from '../../../../src';
|
||||
import {CompareFunction, MinHeap} from '../../../../src';
|
||||
|
||||
describe('MinHeap Operation Test', () => {
|
||||
it('should numeric Min Heap operations be proper', function () {
|
||||
const minNumHeap = new MinHeap<number>();
|
||||
expect(minNumHeap).toBeInstanceOf(MinHeap);
|
||||
describe('MinHeap', () => {
|
||||
const numberComparator: CompareFunction<number> = (a, b) => a - b;
|
||||
let minHeap: MinHeap<number>;
|
||||
|
||||
minNumHeap.add(1);
|
||||
expect(minNumHeap.has(1)).toBe(true);
|
||||
minNumHeap.add(6);
|
||||
expect(minNumHeap.has(2)).toBe(false);
|
||||
expect(minNumHeap.has(6)).toBe(true);
|
||||
minNumHeap.add(2);
|
||||
expect(minNumHeap.has(2)).toBe(true);
|
||||
minNumHeap.add(0);
|
||||
expect(minNumHeap.has(0)).toBe(true);
|
||||
minNumHeap.add(5);
|
||||
expect(minNumHeap.has(5)).toBe(true);
|
||||
minNumHeap.add(9);
|
||||
expect(minNumHeap.has(9)).toBe(true);
|
||||
expect(minNumHeap.size).toBe(6);
|
||||
|
||||
const poll1 = minNumHeap.poll(true);
|
||||
expect(poll1).toBeInstanceOf(HeapItem);
|
||||
poll1 instanceof HeapItem && expect(poll1.val).toBe(0);
|
||||
|
||||
const poll2 = minNumHeap.poll(true);
|
||||
expect(poll2).toBeInstanceOf(HeapItem);
|
||||
poll2 instanceof HeapItem && expect(poll2.val).toBe(1);
|
||||
|
||||
const peek1 = minNumHeap.peek(true);
|
||||
expect(peek1).toBeInstanceOf(HeapItem);
|
||||
peek1 instanceof HeapItem && expect(peek1.val).toBe(2);
|
||||
|
||||
const heapArray = minNumHeap.toArray(true);
|
||||
expect(heapArray).toBeInstanceOf(Array);
|
||||
expect(heapArray.map(item => item?.priority)).toEqual([2, 5, 9, 6]);
|
||||
expect(minNumHeap.size).toBe(4);
|
||||
beforeEach(() => {
|
||||
minHeap = new MinHeap(numberComparator);
|
||||
});
|
||||
|
||||
it('should object Min Heap operations be proper', function () {
|
||||
class MyObject {
|
||||
keyA: string;
|
||||
test('add and poll elements in ascending order', () => {
|
||||
minHeap.add(3);
|
||||
minHeap.add(1);
|
||||
minHeap.add(4);
|
||||
minHeap.add(2);
|
||||
|
||||
constructor(keyA: string) {
|
||||
this.keyA = keyA;
|
||||
}
|
||||
}
|
||||
expect(minHeap.poll()).toBe(1);
|
||||
expect(minHeap.poll()).toBe(2);
|
||||
expect(minHeap.poll()).toBe(3);
|
||||
expect(minHeap.poll()).toBe(4);
|
||||
});
|
||||
|
||||
const minObjHeap = new MinHeap<MyObject>();
|
||||
test('peek at the top element without removing it', () => {
|
||||
minHeap.add(3);
|
||||
minHeap.add(1);
|
||||
minHeap.add(4);
|
||||
minHeap.add(2);
|
||||
|
||||
const obj1 = new MyObject('a1'),
|
||||
obj6 = new MyObject('a6'),
|
||||
obj2 = new MyObject('a2'),
|
||||
obj0 = new MyObject('a0');
|
||||
minObjHeap.add(1, obj1);
|
||||
expect(minObjHeap.has(obj1)).toBe(true);
|
||||
expect(minObjHeap.has(obj6)).toBe(false);
|
||||
minObjHeap.add(6, obj6);
|
||||
expect(minObjHeap.has(obj6)).toBe(true);
|
||||
minObjHeap.add(2, obj2);
|
||||
expect(minObjHeap.has(obj2)).toBe(true);
|
||||
minObjHeap.add(0, obj0);
|
||||
expect(minObjHeap.has(obj0)).toBe(true);
|
||||
expect(minHeap.peek()).toBe(1);
|
||||
expect(minHeap.size).toBe(4);
|
||||
});
|
||||
|
||||
const peek = minObjHeap.peek(true);
|
||||
peek && peek.val && expect(peek.val.keyA).toBe('a0');
|
||||
test('sort elements in ascending order', () => {
|
||||
minHeap.add(3);
|
||||
minHeap.add(1);
|
||||
minHeap.add(4);
|
||||
minHeap.add(2);
|
||||
|
||||
const heapToArr = minObjHeap.toArray(true);
|
||||
expect(heapToArr.map(item => item?.val?.keyA)).toEqual(['a0', 'a1', 'a2', 'a6']);
|
||||
const sortedArray = minHeap.sort();
|
||||
expect(sortedArray).toEqual([1, 2, 3, 4]);
|
||||
});
|
||||
|
||||
const values = ['a0', 'a1', 'a2', 'a6'];
|
||||
let i = 0;
|
||||
while (minObjHeap.size > 0) {
|
||||
const polled = minObjHeap.poll(true);
|
||||
expect(polled).toBeInstanceOf(HeapItem);
|
||||
polled && expect(polled.val).toBeInstanceOf(MyObject);
|
||||
polled && polled.val && expect(polled.val.keyA).toBe(values[i]);
|
||||
i++;
|
||||
}
|
||||
test('check if the heap is empty', () => {
|
||||
expect(minHeap.isEmpty()).toBe(true);
|
||||
|
||||
minHeap.add(5);
|
||||
expect(minHeap.isEmpty()).toBe(false);
|
||||
|
||||
minHeap.poll();
|
||||
expect(minHeap.isEmpty()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -17,11 +17,8 @@ describe('MaxPriorityQueue Operation Test', () => {
|
|||
});
|
||||
|
||||
it('should add elements and maintain heap property in a object MaxPriorityQueue', () => {
|
||||
const priorityQueue = new MaxPriorityQueue<{keyA: number}>({
|
||||
nodes: [{keyA: 5}, {keyA: 3}, {keyA: 1}],
|
||||
comparator: (a, b) => b.keyA - a.keyA
|
||||
});
|
||||
|
||||
const priorityQueue = new MaxPriorityQueue<{keyA: number}>((a, b) => b.keyA - a.keyA);
|
||||
priorityQueue.refill([{keyA: 5}, {keyA: 3}, {keyA: 1}]);
|
||||
priorityQueue.add({keyA: 7});
|
||||
|
||||
expect(priorityQueue.poll()?.keyA).toBe(7);
|
||||
|
@ -56,7 +53,8 @@ describe('MaxPriorityQueue Operation Test', () => {
|
|||
|
||||
it('should correctly heapify an array', () => {
|
||||
const array = [5, 3, 7, 1];
|
||||
const heap = MaxPriorityQueue.heapify<number>({nodes: array});
|
||||
const heap = MaxPriorityQueue.heapify<number>(array, (a, b) => b - a);
|
||||
heap.refill(array);
|
||||
|
||||
expect(heap.poll()).toBe(7);
|
||||
expect(heap.poll()).toBe(5);
|
||||
|
@ -66,7 +64,7 @@ describe('MaxPriorityQueue Operation Test', () => {
|
|||
|
||||
it('should correctly heapify an object array', () => {
|
||||
const nodes = [{keyA: 5}, {keyA: 3}, {keyA: 7}, {keyA: 1}];
|
||||
const maxPQ = MaxPriorityQueue.heapify<{keyA: number}>({nodes, comparator: (a, b) => b.keyA - a.keyA});
|
||||
const maxPQ = MaxPriorityQueue.heapify<{keyA: number}>(nodes, (a, b) => b.keyA - a.keyA);
|
||||
|
||||
expect(maxPQ.poll()?.keyA).toBe(7);
|
||||
expect(maxPQ.poll()?.keyA).toBe(5);
|
||||
|
@ -81,8 +79,8 @@ describe('MaxPriorityQueue Performance Test', () => {
|
|||
new Set<number>(Array.from(new Array(magnitude.LINEAR), () => Math.floor(Math.random() * magnitude.LINEAR * 100)))
|
||||
);
|
||||
expect(nodes.length).toBeGreaterThan(magnitude.LINEAR / 2);
|
||||
const maxPQ = new MaxPriorityQueue<number>({nodes});
|
||||
|
||||
const maxPQ = new MaxPriorityQueue<number>();
|
||||
maxPQ.refill(nodes);
|
||||
let prev = Number.MAX_SAFE_INTEGER;
|
||||
const startTime = performance.now();
|
||||
while (maxPQ.size > 0) {
|
||||
|
|
|
@ -2,54 +2,37 @@ import {PriorityQueue} from '../../../../src';
|
|||
import {getRandomInt} from '../../../utils';
|
||||
|
||||
describe('PriorityQueue Operation Test', () => {
|
||||
it('should validate a priority queue', () => {
|
||||
const minPQ = new PriorityQueue<number>({nodes: [1, 5, 7, 9, 3, 6, 2], comparator: (a, b) => a - b});
|
||||
|
||||
expect(minPQ.isValid()).toBe(true);
|
||||
expect(PriorityQueue.isPriorityQueueified({nodes: minPQ.nodes, comparator: (a, b) => a - b})).toBe(true);
|
||||
expect(PriorityQueue.isPriorityQueueified({nodes: minPQ.nodes, comparator: (a, b) => b - a})).toBe(false);
|
||||
expect(
|
||||
PriorityQueue.isPriorityQueueified({
|
||||
nodes: [1, 5, 7, 9, 3, 6, 2],
|
||||
comparator: (a, b) => b - a
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('should PriorityQueue poll, pee, heapify, toArray work well', function () {
|
||||
const minPQ = new PriorityQueue<number>({nodes: [5, 2, 3, 4, 6, 1], comparator: (a, b) => a - b});
|
||||
const minPQ = new PriorityQueue<number>((a, b) => a - b);
|
||||
minPQ.refill([5, 2, 3, 4, 6, 1]);
|
||||
expect(minPQ.toArray()).toEqual([1, 2, 3, 4, 6, 5]);
|
||||
minPQ.poll();
|
||||
minPQ.poll();
|
||||
minPQ.poll();
|
||||
expect(minPQ.toArray()).toEqual([4, 5, 6]);
|
||||
expect(minPQ.peek()).toBe(4);
|
||||
expect(
|
||||
PriorityQueue.heapify({
|
||||
nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10],
|
||||
comparator: (a, b) => a - b
|
||||
}).toArray()
|
||||
).toEqual([1, 2, 3, 5, 6, 7, 8, 9, 10]);
|
||||
expect(PriorityQueue.heapify([3, 2, 1, 5, 6, 7, 8, 9, 10], (a, b) => a - b).toArray()).toEqual([
|
||||
1, 2, 3, 5, 6, 7, 8, 9, 10
|
||||
]);
|
||||
});
|
||||
|
||||
it('should Max PriorityQueue poll, peek, heapify, toArray work well', function () {
|
||||
const maxPriorityQueue = new PriorityQueue<number>({nodes: [5, 2, 3, 4, 6, 1], comparator: (a, b) => b - a});
|
||||
const maxPriorityQueue = new PriorityQueue<number>((a, b) => b - a);
|
||||
maxPriorityQueue.refill([5, 2, 3, 4, 6, 1]);
|
||||
expect(maxPriorityQueue.toArray()).toEqual([6, 5, 3, 4, 2, 1]);
|
||||
maxPriorityQueue.poll();
|
||||
maxPriorityQueue.poll();
|
||||
maxPriorityQueue.poll();
|
||||
expect(maxPriorityQueue.toArray()).toEqual([3, 2, 1]);
|
||||
expect(maxPriorityQueue.peek()).toBe(3);
|
||||
expect(
|
||||
PriorityQueue.heapify({
|
||||
nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10],
|
||||
comparator: (a, b) => a - b
|
||||
}).toArray()
|
||||
).toEqual([1, 2, 3, 5, 6, 7, 8, 9, 10]);
|
||||
expect(PriorityQueue.heapify([3, 2, 1, 5, 6, 7, 8, 9, 10], (a, b) => a - b).toArray()).toEqual([
|
||||
1, 2, 3, 5, 6, 7, 8, 9, 10
|
||||
]);
|
||||
});
|
||||
|
||||
it('should PriorityQueue clone, sort, getNodes, dfs work well', function () {
|
||||
const minPQ1 = new PriorityQueue<number>({nodes: [2, 5, 8, 3, 1, 6, 7, 4], comparator: (a, b) => a - b});
|
||||
const minPQ1 = new PriorityQueue<number>((a, b) => a - b);
|
||||
minPQ1.refill([2, 5, 8, 3, 1, 6, 7, 4]);
|
||||
const clonedPriorityQueue = minPQ1.clone();
|
||||
expect(clonedPriorityQueue.getNodes()).toEqual(minPQ1.getNodes());
|
||||
expect(clonedPriorityQueue.sort()).toEqual([1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
|
@ -62,7 +45,8 @@ describe('PriorityQueue Operation Test', () => {
|
|||
describe('Priority Queue Performance Test', () => {
|
||||
it('should numeric heap work well', function () {
|
||||
const values = Array.from(new Array(10000), () => getRandomInt(1, 10000000));
|
||||
const minPriorityQueue = new PriorityQueue<number>({nodes: values, comparator: (a, b) => a - b});
|
||||
const minPriorityQueue = new PriorityQueue<number>((a, b) => a - b);
|
||||
minPriorityQueue.refill(values);
|
||||
const sorted = minPriorityQueue.sort();
|
||||
expect(sorted).toEqual(values.sort((a, b) => a - b));
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue