Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for complex data to PriorityQueue #186

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
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
Prev Previous commit
Next Next commit
add ability to change priority for a group of elements
appleJax committed Aug 30, 2018
commit de57051cd2ddd6fc3318c88505e239fb987c19b9
64 changes: 41 additions & 23 deletions src/data-structures/heap/Heap.js
Original file line number Diff line number Diff line change
@@ -155,31 +155,40 @@ export default class Heap {
// We need to find item index to remove each time after removal since
// indices are being changed after each heapify process.
const indexToRemove = this.find(item, comparator).pop();
this.removeIndex(indexToRemove);
}

return this;
}

// If we need to remove last child in the heap then just remove it.
// There is no need to heapify the heap afterwards.
if (indexToRemove === (this.heapContainer.length - 1)) {
this.heapContainer.pop();
/**
* @param {number} indexToRemove
* @return {Heap}
*/
removeIndex(indexToRemove) {
// If we need to remove last child in the heap then just remove it.
// There is no need to heapify the heap afterwards.
if (indexToRemove === (this.heapContainer.length - 1)) {
this.heapContainer.pop();
} else {
// Move last element in heap to the vacant (removed) position.
this.heapContainer[indexToRemove] = this.heapContainer.pop();

// Get parent.
const parentItem = this.parent(indexToRemove);

// If there is no parent or parent is in correct order with the node
// we're going to delete then heapify down. Otherwise heapify up.
if (
this.hasLeftChild(indexToRemove)
&& (
!parentItem
|| this.pairIsInCorrectOrder(parentItem, this.heapContainer[indexToRemove])
)
) {
this.heapifyDown(indexToRemove);
} else {
// Move last element in heap to the vacant (removed) position.
this.heapContainer[indexToRemove] = this.heapContainer.pop();

// Get parent.
const parentItem = this.parent(indexToRemove);

// If there is no parent or parent is in correct order with the node
// we're going to delete then heapify down. Otherwise heapify up.
if (
this.hasLeftChild(indexToRemove)
&& (
!parentItem
|| this.pairIsInCorrectOrder(parentItem, this.heapContainer[indexToRemove])
)
) {
this.heapifyDown(indexToRemove);
} else {
this.heapifyUp(indexToRemove);
}
this.heapifyUp(indexToRemove);
}
}

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

/**
*
* @param {number} index
* @return {*}
*/
getElementAtIndex(index) {
return this.heapContainer[index];
}

/**
* @return {boolean}
*/
18 changes: 16 additions & 2 deletions src/data-structures/priority-queue/PriorityQueue.js
Original file line number Diff line number Diff line change
@@ -50,8 +50,22 @@ export default class PriorityQueue extends MinHeap {
*/
changePriority(item, priority, maybeComparator) {
const comparator = this.getValueComparator(maybeComparator);
this.remove(item, comparator);
this.add(item, priority);
const numberOfItemsToRemove = this.find(item, comparator).length;
const itemsToUpdate = [];

for (let iteration = 0; iteration < numberOfItemsToRemove; iteration += 1) {
// We need to find item index to remove each time after removal since
// indices are being changed after each heapify process.
const indexToRemove = this.find(item, comparator).pop();
const itemToUpdate = this.getElementAtIndex(indexToRemove);
itemsToUpdate.push(itemToUpdate);
this.priorities.delete(itemToUpdate);
this.removeIndex(indexToRemove);
}

itemsToUpdate.forEach((itemToUpdate) => {
this.add(itemToUpdate, priority);
});

return this;
}
29 changes: 29 additions & 0 deletions src/data-structures/priority-queue/__test__/PriorityQueue.test.js
Original file line number Diff line number Diff line change
@@ -94,6 +94,35 @@ describe('PriorityQueue', () => {
expect(priorityQueue.poll()).toBe(JOB1);
});

it('should be possible to change the priority of a group of elements', () => {
const A = 'a';
const B = 'b';
const jobA1 = { type: A, id: 1 };
const jobB1 = { type: B, id: 2 };
const jobB2 = { type: B, id: 3 };

const priorityQueue = new PriorityQueue();

priorityQueue.add(jobA1, 2);
priorityQueue.add(jobB1, 8);
priorityQueue.add(jobB2, 9);

expect(priorityQueue.peek()).toBe(jobA1);

const compareByType = (a, b) => {
if (a.type === b.type) {
return 0;
}

return a.type < b.type ? -1 : 1;
};

priorityQueue.changePriority({ type: B }, 1, compareByType);

expect(priorityQueue.poll().type).toBe(B);
expect(priorityQueue.poll().type).toBe(B);
});

it('should be possible to search in priority queue by value', () => {
const priorityQueue = new PriorityQueue();