Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit de57051

Browse files
committedAug 30, 2018
add ability to change priority for a group of elements
1 parent 7715bcb commit de57051

File tree

3 files changed

+86
-25
lines changed

3 files changed

+86
-25
lines changed
 

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

+41-23
Original file line numberDiff line numberDiff line change
@@ -155,31 +155,40 @@ export default class Heap {
155155
// We need to find item index to remove each time after removal since
156156
// indices are being changed after each heapify process.
157157
const indexToRemove = this.find(item, comparator).pop();
158+
this.removeIndex(indexToRemove);
159+
}
160+
161+
return this;
162+
}
158163

159-
// If we need to remove last child in the heap then just remove it.
160-
// There is no need to heapify the heap afterwards.
161-
if (indexToRemove === (this.heapContainer.length - 1)) {
162-
this.heapContainer.pop();
164+
/**
165+
* @param {number} indexToRemove
166+
* @return {Heap}
167+
*/
168+
removeIndex(indexToRemove) {
169+
// If we need to remove last child in the heap then just remove it.
170+
// There is no need to heapify the heap afterwards.
171+
if (indexToRemove === (this.heapContainer.length - 1)) {
172+
this.heapContainer.pop();
173+
} else {
174+
// Move last element in heap to the vacant (removed) position.
175+
this.heapContainer[indexToRemove] = this.heapContainer.pop();
176+
177+
// Get parent.
178+
const parentItem = this.parent(indexToRemove);
179+
180+
// If there is no parent or parent is in correct order with the node
181+
// we're going to delete then heapify down. Otherwise heapify up.
182+
if (
183+
this.hasLeftChild(indexToRemove)
184+
&& (
185+
!parentItem
186+
|| this.pairIsInCorrectOrder(parentItem, this.heapContainer[indexToRemove])
187+
)
188+
) {
189+
this.heapifyDown(indexToRemove);
163190
} else {
164-
// Move last element in heap to the vacant (removed) position.
165-
this.heapContainer[indexToRemove] = this.heapContainer.pop();
166-
167-
// Get parent.
168-
const parentItem = this.parent(indexToRemove);
169-
170-
// If there is no parent or parent is in correct order with the node
171-
// we're going to delete then heapify down. Otherwise heapify up.
172-
if (
173-
this.hasLeftChild(indexToRemove)
174-
&& (
175-
!parentItem
176-
|| this.pairIsInCorrectOrder(parentItem, this.heapContainer[indexToRemove])
177-
)
178-
) {
179-
this.heapifyDown(indexToRemove);
180-
} else {
181-
this.heapifyUp(indexToRemove);
182-
}
191+
this.heapifyUp(indexToRemove);
183192
}
184193
}
185194

@@ -203,6 +212,15 @@ export default class Heap {
203212
return foundItemIndices;
204213
}
205214

215+
/**
216+
*
217+
* @param {number} index
218+
* @return {*}
219+
*/
220+
getElementAtIndex(index) {
221+
return this.heapContainer[index];
222+
}
223+
206224
/**
207225
* @return {boolean}
208226
*/

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

+16-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,22 @@ export default class PriorityQueue extends MinHeap {
5050
*/
5151
changePriority(item, priority, maybeComparator) {
5252
const comparator = this.getValueComparator(maybeComparator);
53-
this.remove(item, comparator);
54-
this.add(item, priority);
53+
const numberOfItemsToRemove = this.find(item, comparator).length;
54+
const itemsToUpdate = [];
55+
56+
for (let iteration = 0; iteration < numberOfItemsToRemove; iteration += 1) {
57+
// We need to find item index to remove each time after removal since
58+
// indices are being changed after each heapify process.
59+
const indexToRemove = this.find(item, comparator).pop();
60+
const itemToUpdate = this.getElementAtIndex(indexToRemove);
61+
itemsToUpdate.push(itemToUpdate);
62+
this.priorities.delete(itemToUpdate);
63+
this.removeIndex(indexToRemove);
64+
}
65+
66+
itemsToUpdate.forEach((itemToUpdate) => {
67+
this.add(itemToUpdate, priority);
68+
});
5569

5670
return this;
5771
}

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

+29
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,35 @@ describe('PriorityQueue', () => {
9494
expect(priorityQueue.poll()).toBe(JOB1);
9595
});
9696

97+
it('should be possible to change the priority of a group of elements', () => {
98+
const A = 'a';
99+
const B = 'b';
100+
const jobA1 = { type: A, id: 1 };
101+
const jobB1 = { type: B, id: 2 };
102+
const jobB2 = { type: B, id: 3 };
103+
104+
const priorityQueue = new PriorityQueue();
105+
106+
priorityQueue.add(jobA1, 2);
107+
priorityQueue.add(jobB1, 8);
108+
priorityQueue.add(jobB2, 9);
109+
110+
expect(priorityQueue.peek()).toBe(jobA1);
111+
112+
const compareByType = (a, b) => {
113+
if (a.type === b.type) {
114+
return 0;
115+
}
116+
117+
return a.type < b.type ? -1 : 1;
118+
};
119+
120+
priorityQueue.changePriority({ type: B }, 1, compareByType);
121+
122+
expect(priorityQueue.poll().type).toBe(B);
123+
expect(priorityQueue.poll().type).toBe(B);
124+
});
125+
97126
it('should be possible to search in priority queue by value', () => {
98127
const priorityQueue = new PriorityQueue();
99128

0 commit comments

Comments
 (0)
Please sign in to comment.