Skip to content

Commit 8b057b1

Browse files
committedMay 3, 2018
Make it possible to change priority of PriorityQueue.
1 parent 9c1b8e4 commit 8b057b1

File tree

3 files changed

+105
-4
lines changed

3 files changed

+105
-4
lines changed
 

‎src/data-structures/heap/MinHeap.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -136,16 +136,18 @@ export default class MinHeap {
136136

137137
/**
138138
* @param {*} item
139+
* @param {Comparator} [customFindingComparator]
139140
* @return {MinHeap}
140141
*/
141-
remove(item) {
142+
remove(item, customFindingComparator) {
142143
// Find number of items to remove.
143144
const numberOfItemsToRemove = this.find(item).length;
145+
const customComparator = customFindingComparator || this.compare;
144146

145147
for (let iteration = 0; iteration < numberOfItemsToRemove; iteration += 1) {
146148
// We need to find item index to remove each time after removal since
147149
// indices are being change after each heapify process.
148-
const indexToRemove = this.find(item).pop();
150+
const indexToRemove = this.find(item, customComparator).pop();
149151

150152
// If we need to remove last child in the heap then just remove it.
151153
// There is no need to heapify the heap afterwards.
@@ -180,13 +182,15 @@ export default class MinHeap {
180182

181183
/**
182184
* @param {*} item
185+
* @param {Comparator} [customComparator]
183186
* @return {Number[]}
184187
*/
185-
find(item) {
188+
find(item, customComparator) {
186189
const foundItemIndices = [];
190+
const comparator = customComparator || this.compare;
187191

188192
for (let itemIndex = 0; itemIndex < this.heapContainer.length; itemIndex += 1) {
189-
if (this.compare.equal(item, this.heapContainer[itemIndex])) {
193+
if (comparator.equal(item, this.heapContainer[itemIndex])) {
190194
foundItemIndices.push(itemIndex);
191195
}
192196
}

‎src/data-structures/priority-queue/PriorityQueue.js

+43
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,54 @@ export default class PriorityQueue extends MinHeap {
1010
this.compare = new Comparator(this.comparePriority.bind(this));
1111
}
1212

13+
/**
14+
* @param {*} item
15+
* @param {number} [priority]
16+
* @return {PriorityQueue}
17+
*/
1318
add(item, priority = 0) {
1419
this.priorities[item] = priority;
1520
super.add(item);
21+
22+
return this;
23+
}
24+
25+
/**
26+
* @param {*} item
27+
* @param {Comparator} [customFindingComparator]
28+
* @return {PriorityQueue}
29+
*/
30+
remove(item, customFindingComparator) {
31+
super.remove(item, customFindingComparator);
32+
delete this.priorities[item];
33+
34+
return this;
35+
}
36+
37+
/**
38+
* @param {*} item
39+
* @param {number} priority
40+
* @return {PriorityQueue}
41+
*/
42+
changePriority(item, priority) {
43+
const customFindingComparator = new Comparator((a, b) => {
44+
if (a === b) {
45+
return 0;
46+
}
47+
return a < b ? -1 : 1;
48+
});
49+
50+
this.remove(item, customFindingComparator);
51+
this.add(item, priority);
52+
53+
return this;
1654
}
1755

56+
/**
57+
* @param {*} a
58+
* @param {*} b
59+
* @return {number}
60+
*/
1861
comparePriority(a, b) {
1962
if (this.priorities[a] === this.priorities[b]) {
2063
return 0;

‎src/data-structures/priority-queue/__test__/PriorityQueue.test.js

+54
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,58 @@ describe('PriorityQueue', () => {
3333
expect(priorityQueue.poll()).toBe(10);
3434
expect(priorityQueue.poll()).toBe(5);
3535
});
36+
37+
it('should be possible to change priority of internal nodes', () => {
38+
const priorityQueue = new PriorityQueue();
39+
40+
priorityQueue.add(10, 1);
41+
priorityQueue.add(5, 2);
42+
priorityQueue.add(100, 0);
43+
priorityQueue.add(200, 0);
44+
45+
priorityQueue.changePriority(100, 10);
46+
priorityQueue.changePriority(10, 20);
47+
48+
expect(priorityQueue.poll()).toBe(200);
49+
expect(priorityQueue.poll()).toBe(5);
50+
expect(priorityQueue.poll()).toBe(100);
51+
expect(priorityQueue.poll()).toBe(10);
52+
});
53+
54+
it('should be possible to change priority of head node', () => {
55+
const priorityQueue = new PriorityQueue();
56+
57+
priorityQueue.add(10, 1);
58+
priorityQueue.add(5, 2);
59+
priorityQueue.add(100, 0);
60+
priorityQueue.add(200, 0);
61+
62+
priorityQueue.changePriority(200, 10);
63+
priorityQueue.changePriority(10, 20);
64+
65+
expect(priorityQueue.poll()).toBe(100);
66+
expect(priorityQueue.poll()).toBe(5);
67+
expect(priorityQueue.poll()).toBe(200);
68+
expect(priorityQueue.poll()).toBe(10);
69+
});
70+
71+
it('should be possible to change priority along with node addition', () => {
72+
const priorityQueue = new PriorityQueue();
73+
74+
priorityQueue.add(10, 1);
75+
priorityQueue.add(5, 2);
76+
priorityQueue.add(100, 0);
77+
priorityQueue.add(200, 0);
78+
79+
priorityQueue.changePriority(200, 10);
80+
priorityQueue.changePriority(10, 20);
81+
82+
priorityQueue.add(15, 15);
83+
84+
expect(priorityQueue.poll()).toBe(100);
85+
expect(priorityQueue.poll()).toBe(5);
86+
expect(priorityQueue.poll()).toBe(200);
87+
expect(priorityQueue.poll()).toBe(15);
88+
expect(priorityQueue.poll()).toBe(10);
89+
});
3690
});

0 commit comments

Comments
 (0)
Please sign in to comment.