Refactor MinHeap.

This commit is contained in:
Oleksii Trekhleb 2018-04-03 18:17:14 +03:00
parent 062f5a4929
commit 138c3d9905
5 changed files with 68 additions and 9 deletions

View File

@ -7,6 +7,7 @@
}, },
"rules": { "rules": {
"no-bitwise": "off", "no-bitwise": "off",
"no-lonely-if": "off" "no-lonely-if": "off",
"class-methods-use-this": "warn"
} }
} }

View File

@ -9,8 +9,9 @@
3. [Stack](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/stack) 3. [Stack](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/stack)
4. [Hash Table](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/hash-table) 4. [Hash Table](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/hash-table)
5. [Heap](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/heap) 5. [Heap](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/heap)
5. [Trie](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/trie) 6. [Priority Queue](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/priority-queue)
6. [Tree](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/tree) 7. [Trie](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/trie)
8. [Tree](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/tree)
* [Binary Search Tree](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/tree/binary-search-tree) * [Binary Search Tree](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/tree/binary-search-tree)
## [Algorithms](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms) ## [Algorithms](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms)

View File

@ -85,7 +85,7 @@ export default class MinHeap {
while ( while (
MinHeap.hasParent(currentIndex) && MinHeap.hasParent(currentIndex) &&
MinHeap.lessThen(this.heapContainer[currentIndex], this.parent(currentIndex)) this.lessThen(this.heapContainer[currentIndex], this.parent(currentIndex))
) { ) {
this.swap(currentIndex, MinHeap.getParentIndex(currentIndex)); this.swap(currentIndex, MinHeap.getParentIndex(currentIndex));
currentIndex = MinHeap.getParentIndex(currentIndex); currentIndex = MinHeap.getParentIndex(currentIndex);
@ -101,14 +101,14 @@ export default class MinHeap {
while (this.hasLeftChild(currentIndex)) { while (this.hasLeftChild(currentIndex)) {
if ( if (
this.hasRightChild(currentIndex) && this.hasRightChild(currentIndex) &&
MinHeap.lessThen(this.rightChild(currentIndex), this.leftChild(currentIndex)) this.lessThen(this.rightChild(currentIndex), this.leftChild(currentIndex))
) { ) {
nextIndex = MinHeap.getRightChildIndex(currentIndex); nextIndex = MinHeap.getRightChildIndex(currentIndex);
} else { } else {
nextIndex = MinHeap.getLeftChildIndex(currentIndex); nextIndex = MinHeap.getLeftChildIndex(currentIndex);
} }
if (MinHeap.lessThen(this.heapContainer[currentIndex], this.heapContainer[nextIndex])) { if (this.lessThen(this.heapContainer[currentIndex], this.heapContainer[nextIndex])) {
break; break;
} }
@ -121,7 +121,7 @@ export default class MinHeap {
return this.heapContainer.toString(); return this.heapContainer.toString();
} }
static compare(a, b) { compare(a, b) {
if (a === b) { if (a === b) {
return 0; return 0;
} }
@ -129,7 +129,7 @@ export default class MinHeap {
return a < b ? -1 : 1; return a < b ? -1 : 1;
} }
static lessThen(a, b) { lessThen(a, b) {
return MinHeap.compare(a, b) === -1; return this.compare(a, b) === -1;
} }
} }

View File

@ -0,0 +1,23 @@
import MinHeap from '../heap/MinHeap';
// It is the same as min heap except that when comparing to elements
// we take into account not element's value but rather its priority.
export default class PriorityQueue extends MinHeap {
constructor() {
super();
this.priorities = {};
}
add(item, priority = 0) {
this.priorities[item] = priority;
super.add(item);
}
compare(a, b) {
if (this.priorities[a] === this.priorities[b]) {
return 0;
}
return this.priorities[a] < this.priorities[b] ? -1 : 1;
}
}

View File

@ -0,0 +1,34 @@
import PriorityQueue from '../PriorityQueue';
describe('PriorityQueue', () => {
it('should create default priority queue', () => {
const priorityQueue = new PriorityQueue();
expect(priorityQueue).toBeDefined();
});
it('should insert items to the queue and respect priorities', () => {
const priorityQueue = new PriorityQueue();
priorityQueue.add(10, 1);
expect(priorityQueue.peek()).toBe(10);
priorityQueue.add(5, 2);
expect(priorityQueue.peek()).toBe(10);
priorityQueue.add(100, 0);
expect(priorityQueue.peek()).toBe(100);
});
it('should poll from queue with respect to priorities', () => {
const priorityQueue = new PriorityQueue();
priorityQueue.add(10, 1);
priorityQueue.add(5, 2);
priorityQueue.add(100, 0);
expect(priorityQueue.poll()).toBe(100);
expect(priorityQueue.poll()).toBe(10);
expect(priorityQueue.poll()).toBe(5);
});
});