From 10e5a8f6555ba22aa69d0c53be2a7abf4f490c50 Mon Sep 17 00:00:00 2001 From: Eyas Ranjous Date: Tue, 28 Jul 2026 19:49:43 -0700 Subject: [PATCH 1/2] add fix function --- CHANGELOG.md | 3 +++ README.md | 19 +++++++++++++++++++ src/maxPriorityQueue.d.ts | 1 + src/minPriorityQueue.d.ts | 1 + src/priorityQueue.d.ts | 1 + src/priorityQueue.js | 10 ++++++++++ test/PriorityQueue.test.js | 34 ++++++++++++++++++++++++++++++++++ test/maxPriorityQueue.test.js | 34 ++++++++++++++++++++++++++++++++++ test/minPriorityQueue.test.js | 35 ++++++++++++++++++++++++++++++++++- 9 files changed, 137 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6b9257..6cce0e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/README.md b/README.md index 0910b29..c0f9197 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,22 @@ ## Docs https://datastructures-js.info/docs/priority-queue + +## fix +Fixes element positions in the queue in O(n) runtime. + +```js +const { MinPriorityQueue } = require('@datastructures-js/priority-queue'); + +const first = { id: 1, priority: 1 }; +const second = { id: 2, priority: 2 }; +const queue = new MinPriorityQueue((value) => value.priority); + +queue.enqueue(first); +queue.enqueue(second); +console.log(queue.front()); // { id: 1, priority: 1 } + +second.priority = 0; +queue.fix(); +console.log(queue.front()); // { id: 2, priority: 0 } +``` diff --git a/src/maxPriorityQueue.d.ts b/src/maxPriorityQueue.d.ts index 5c0f5bd..0b50baf 100644 --- a/src/maxPriorityQueue.d.ts +++ b/src/maxPriorityQueue.d.ts @@ -5,6 +5,7 @@ import { LegacyOptions } from './minPriorityQueue'; export interface MaxPriorityQueue extends PriorityQueue { enqueue(value: T): MaxPriorityQueue; push(value: T): MaxPriorityQueue; + fix(): MaxPriorityQueue; } export const MaxPriorityQueue: { diff --git a/src/minPriorityQueue.d.ts b/src/minPriorityQueue.d.ts index 3ac4475..69c36a6 100644 --- a/src/minPriorityQueue.d.ts +++ b/src/minPriorityQueue.d.ts @@ -8,6 +8,7 @@ export interface LegacyOptions { export interface MinPriorityQueue extends PriorityQueue { enqueue(value: T): MinPriorityQueue; push(value: T): MinPriorityQueue; + fix(): MinPriorityQueue; } export const MinPriorityQueue: { diff --git a/src/priorityQueue.d.ts b/src/priorityQueue.d.ts index c3a5f98..0c79b01 100644 --- a/src/priorityQueue.d.ts +++ b/src/priorityQueue.d.ts @@ -12,6 +12,7 @@ export interface PriorityQueue extends Iterable { pop(): T | null; remove(cb: (value: T) => boolean): T[]; contains(cb: (value: T) => boolean): boolean; + fix(): PriorityQueue; toArray(): T[]; clear(): void; } diff --git a/src/priorityQueue.js b/src/priorityQueue.js index 1bc876f..31d0a60 100644 --- a/src/priorityQueue.js +++ b/src/priorityQueue.js @@ -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 diff --git a/test/PriorityQueue.test.js b/test/PriorityQueue.test.js index 6462dcb..7dfdb4b 100644 --- a/test/PriorityQueue.test.js +++ b/test/PriorityQueue.test.js @@ -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]; diff --git a/test/maxPriorityQueue.test.js b/test/maxPriorityQueue.test.js index eb8024a..9180e4e 100644 --- a/test/maxPriorityQueue.test.js +++ b/test/maxPriorityQueue.test.js @@ -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', () => { diff --git a/test/minPriorityQueue.test.js b/test/minPriorityQueue.test.js index 30c80e6..447ab47 100644 --- a/test/minPriorityQueue.test.js +++ b/test/minPriorityQueue.test.js @@ -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]; @@ -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', () => { From f1f52358ceae709f053ac4fc5db04471ae9c1015 Mon Sep 17 00:00:00 2001 From: eyas Date: Wed, 29 Jul 2026 01:06:06 -0700 Subject: [PATCH 2/2] remove Removed outdated fix section and example code from README. --- README.md | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/README.md b/README.md index c0f9197..0910b29 100644 --- a/README.md +++ b/README.md @@ -2,22 +2,3 @@ ## Docs https://datastructures-js.info/docs/priority-queue - -## fix -Fixes element positions in the queue in O(n) runtime. - -```js -const { MinPriorityQueue } = require('@datastructures-js/priority-queue'); - -const first = { id: 1, priority: 1 }; -const second = { id: 2, priority: 2 }; -const queue = new MinPriorityQueue((value) => value.priority); - -queue.enqueue(first); -queue.enqueue(second); -console.log(queue.front()); // { id: 1, priority: 1 } - -second.priority = 0; -queue.fix(); -console.log(queue.front()); // { id: 2, priority: 0 } -```