Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
- `.fix()` to repair queue positions after mutable priorities change.

## [6.3.5] - 2025-10-12
### Fixed
- Allows creating queues from list of values in O(n) runtime via constructor & fromArray
Expand Down
1 change: 1 addition & 0 deletions src/maxPriorityQueue.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { LegacyOptions } from './minPriorityQueue';
export interface MaxPriorityQueue<T> extends PriorityQueue<T> {
enqueue(value: T): MaxPriorityQueue<T>;
push(value: T): MaxPriorityQueue<T>;
fix(): MaxPriorityQueue<T>;
}

export const MaxPriorityQueue: {
Expand Down
1 change: 1 addition & 0 deletions src/minPriorityQueue.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface LegacyOptions<T> {
export interface MinPriorityQueue<T> extends PriorityQueue<T> {
enqueue(value: T): MinPriorityQueue<T>;
push(value: T): MinPriorityQueue<T>;
fix(): MinPriorityQueue<T>;
}

export const MinPriorityQueue: {
Expand Down
1 change: 1 addition & 0 deletions src/priorityQueue.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface PriorityQueue<T> extends Iterable<T> {
pop(): T | null;
remove(cb: (value: T) => boolean): T[];
contains(cb: (value: T) => boolean): boolean;
fix(): PriorityQueue<T>;
toArray(): T[];
clear(): void;
}
Expand Down
10 changes: 10 additions & 0 deletions src/priorityQueue.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,16 @@ class PriorityQueue {
return this._heap.isEmpty();
}

/**
* Fixes element positions in the queue
* @public
* @returns {PriorityQueue}
*/
fix() {
this._heap.fix();
return this;
}

/**
* Clears the queue
* @public
Expand Down
34 changes: 34 additions & 0 deletions test/PriorityQueue.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,40 @@ describe('PriorityQueue', () => {
});
});

describe('fix', () => {
it('fixes element positions when multiple priorities change', () => {
const one = { id: 'one', priority: 1 };
const two = { id: 'two', priority: 2 };
const three = { id: 'three', priority: 3 };
const four = { id: 'four', priority: 4 };
const five = { id: 'five', priority: 5 };
const six = { id: 'six', priority: 6 };
const seven = { id: 'seven', priority: 7 };
const qTest = PriorityQueue.fromArray(
[one, two, three, four, five, six, seven],
(a, b) => a.priority - b.priority
);

one.priority = 8;
four.priority = 0;
seven.priority = 3.5;

expect(qTest.fix()).to.equal(qTest);
expect(qTest.size()).to.equal(7);
expect(qTest.toArray()).to.eql([
four,
two,
three,
seven,
five,
six,
one
]);
expect(qTest.front()).to.equal(four);
expect(qTest.back()).to.equal(one);
});
});

describe('iterator', () => {
it('allows iterating on queue elements', () => {
const testArr = [20, 30, 40, 50, 80, 90];
Expand Down
34 changes: 34 additions & 0 deletions test/maxPriorityQueue.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,40 @@ describe('MaxPriorityQueue', () => {
expect(qTest.pop()).to.eql(20);
});
});

describe('fix', () => {
it('fixes element positions when multiple priorities change', () => {
const one = { id: 'one', priority: 1 };
const two = { id: 'two', priority: 2 };
const three = { id: 'three', priority: 3 };
const four = { id: 'four', priority: 4 };
const five = { id: 'five', priority: 5 };
const six = { id: 'six', priority: 6 };
const seven = { id: 'seven', priority: 7 };
const qTest = MaxPriorityQueue.fromArray(
[one, two, three, four, five, six, seven],
(value) => value.priority
);

one.priority = 8;
four.priority = 0;
seven.priority = 3.5;

expect(qTest.fix()).to.equal(qTest);
expect(qTest.size()).to.equal(7);
expect(qTest.toArray()).to.eql([
one,
six,
five,
seven,
three,
two,
four
]);
expect(qTest.front()).to.equal(one);
expect(qTest.back()).to.equal(four);
});
});
});

describe('constructor with initial values', () => {
Expand Down
35 changes: 34 additions & 1 deletion test/minPriorityQueue.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ describe('MinPriorityQueue', () => {
expect(qTest.contains((n) => n === 100)).to.equal(false);
});
});

describe('remove', () => {
it('remove elements that match a criteria', () => {
const testArr = [20, 30, 40, 50, 80, 90];
Expand All @@ -124,6 +124,39 @@ describe('MinPriorityQueue', () => {
});
});

describe('fix', () => {
it('fixes element positions when multiple priorities change', () => {
const one = { id: 'one', priority: 1 };
const two = { id: 'two', priority: 2 };
const three = { id: 'three', priority: 3 };
const four = { id: 'four', priority: 4 };
const five = { id: 'five', priority: 5 };
const six = { id: 'six', priority: 6 };
const seven = { id: 'seven', priority: 7 };
const qTest = MinPriorityQueue.fromArray(
[one, two, three, four, five, six, seven],
(value) => value.priority
);

one.priority = 8;
four.priority = 0;
seven.priority = 3.5;

expect(qTest.fix()).to.equal(qTest);
expect(qTest.size()).to.equal(7);
expect(qTest.toArray()).to.eql([
four,
two,
three,
seven,
five,
six,
one
]);
expect(qTest.front()).to.equal(four);
expect(qTest.back()).to.equal(one);
});
});
});

describe('constructor with initial values', () => {
Expand Down
Loading