Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 827177f

Browse files
feat(heap): add error handling for heaps
BREAKING CHANGE: size is now an attribute rather than a method. Similar to the built-in Map.size and Set.size
1 parent 3a2a24f commit 827177f

File tree

4 files changed

+41
-29
lines changed

4 files changed

+41
-29
lines changed

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
class Heap {
99
constructor(comparator = (a, b) => a - b) {
1010
this.array = [];
11-
this.comparator = (i1, i2) => comparator(this.array[i1], this.array[i2]);
11+
this.comparator = (i1, i2) => {
12+
const value = comparator(this.array[i1], this.array[i2]);
13+
if (Number.isNaN(value)) { throw new Error(`Comparator should evaluate to a number. Got ${value} when comparing ${this.array[i1]} with ${this.array[i2]}`); }
14+
return value;
15+
};
1216
}
1317

1418
/**
@@ -34,8 +38,8 @@ class Heap {
3438
* @runtime O(log n)
3539
*/
3640
remove(index = 0) {
37-
if (!this.size()) return null;
38-
this.swap(index, this.size() - 1); // swap with last
41+
if (!this.size) return null;
42+
this.swap(index, this.size - 1); // swap with last
3943
const value = this.array.pop(); // remove element
4044
this.bubbleDown(index);
4145
return value;
@@ -45,7 +49,7 @@ class Heap {
4549
* Returns the number of elements in this collection.
4650
* @runtime O(1)
4751
*/
48-
size() {
52+
getsize() {
4953
return this.array.length;
5054
}
5155

@@ -54,7 +58,7 @@ class Heap {
5458
* @runtime O(log n)
5559
*/
5660
bubbleUp() {
57-
let index = this.size() - 1;
61+
let index = this.size - 1;
5862
const parent = (i) => Math.ceil(i / 2 - 1);
5963
while (parent(index) >= 0 && this.comparator(parent(index), index) > 0) {
6064
this.swap(parent(index), index);
@@ -70,18 +74,18 @@ class Heap {
7074
let curr = index;
7175
const left = (i) => 2 * i + 1;
7276
const right = (i) => 2 * i + 2;
73-
const getTopChild = (i) => (right(i) < this.size()
77+
const getTopChild = (i) => (right(i) < this.size
7478
&& this.comparator(left(i), right(i)) > 0 ? right(i) : left(i));
7579

76-
while (left(curr) < this.size() && this.comparator(curr, getTopChild(curr)) > 0) {
80+
while (left(curr) < this.size && this.comparator(curr, getTopChild(curr)) > 0) {
7781
const next = getTopChild(curr);
7882
this.swap(curr, next);
7983
curr = next;
8084
}
8185
}
8286

8387
/**
84-
* "Private": Swap elements on the heap
88+
* Swap elements on the heap
8589
* @runtime O(1)
8690
* @param {number} i1 index 1
8791
* @param {number} i2 index 2

‎src/data-structures/heaps/heap.spec.js

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ const PriorityQueue = require('./priority-queue');
33
const MaxHeap = require('./max-heap');
44
const MinHeap = require('./min-heap');
55

6-
[[Heap], [PriorityQueue], [MinHeap]].forEach(([DS, arg]) => {
7-
describe('Min-Heap (Priority Queue)', () => {
6+
[
7+
[Heap],
8+
[PriorityQueue, [], (a, b) => a - b],
9+
[MinHeap],
10+
].forEach(([DS, ...arg]) => {
11+
describe('Min-Heap and Priority Queue', () => {
812
let heap;
913

1014
beforeEach(() => {
11-
heap = new DS(arg);
15+
heap = new DS(...arg);
1216
});
1317

1418
describe('#contructor', () => {
@@ -21,7 +25,7 @@ const MinHeap = require('./min-heap');
2125
it('should add an element', () => {
2226
expect(heap.add(1)).toBe(undefined);
2327
expect(heap.array).toEqual([1]);
24-
expect(heap.size()).toBe(1);
28+
expect(heap.size).toBe(1);
2529
});
2630

2731
it('should keep things in order', () => {
@@ -31,7 +35,7 @@ const MinHeap = require('./min-heap');
3135
expect(heap.array[0]).toEqual(2);
3236
heap.add(1);
3337
expect(heap.array[0]).toEqual(1);
34-
expect(heap.size()).toEqual(3);
38+
expect(heap.size).toEqual(3);
3539
});
3640
});
3741

@@ -40,7 +44,7 @@ const MinHeap = require('./min-heap');
4044
heap.add(1);
4145
heap.add(0);
4246
expect(heap.remove()).toBe(0);
43-
expect(heap.size()).toBe(1);
47+
expect(heap.size).toBe(1);
4448
expect(heap.array).toEqual([1]);
4549
});
4650

@@ -70,19 +74,23 @@ const MinHeap = require('./min-heap');
7074
expect(heap.remove()).toEqual(1);
7175
expect(heap.remove()).toEqual(2);
7276
expect(heap.remove()).toEqual(3);
73-
expect(heap.size()).toBe(0);
77+
expect(heap.size).toBe(0);
7478
});
7579
});
7680
});
7781
});
7882
});
7983

80-
[[Heap, (a, b) => b - a], [PriorityQueue, (a, b) => b - a], [MaxHeap]].forEach(([DS, arg]) => {
84+
[
85+
[Heap, (a, b) => b - a],
86+
[PriorityQueue, [], (a, b) => b - a],
87+
[MaxHeap],
88+
].forEach(([DS, ...arg]) => {
8189
describe('Max-Heap (Priority Queue)', () => {
8290
let heap;
8391

8492
beforeEach(() => {
85-
heap = new DS(arg);
93+
heap = new DS(...arg);
8694
});
8795

8896
describe('#contructor', () => {
@@ -95,7 +103,7 @@ const MinHeap = require('./min-heap');
95103
it('should add an element', () => {
96104
expect(heap.add(1)).toBe(undefined);
97105
expect(heap.array).toEqual([1]);
98-
expect(heap.size()).toBe(1);
106+
expect(heap.size).toBe(1);
99107
});
100108

101109
it('should keep things in order', () => {
@@ -105,7 +113,7 @@ const MinHeap = require('./min-heap');
105113
expect(heap.array[0]).toEqual(2);
106114
heap.add(3);
107115
expect(heap.array[0]).toEqual(3);
108-
expect(heap.size()).toEqual(3);
116+
expect(heap.size).toEqual(3);
109117
});
110118
});
111119

@@ -114,7 +122,7 @@ const MinHeap = require('./min-heap');
114122
heap.add(1);
115123
heap.add(0);
116124
expect(heap.remove()).toBe(1);
117-
expect(heap.size()).toBe(1);
125+
expect(heap.size).toBe(1);
118126
expect(heap.array).toEqual([0]);
119127
});
120128

@@ -156,7 +164,7 @@ const MinHeap = require('./min-heap');
156164
expect(heap.remove()).toEqual(2);
157165
expect(heap.remove()).toEqual(1);
158166
expect(heap.remove()).toEqual(0);
159-
expect(heap.size()).toBe(0);
167+
expect(heap.size).toBe(0);
160168
});
161169
});
162170
});

‎src/data-structures/heaps/median-heap.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ class MedianHeap {
3030
}
3131

3232
// rebalance if the sizes of the heaps differ by more than one element
33-
if (Math.abs(this.min.size() - this.max.size()) > 1) {
33+
if (Math.abs(this.min.size - this.max.size) > 1) {
3434
// extract the min/max from the heap with more elements and insert it into the other heap.
35-
if (this.min.size() > this.max.size()) {
35+
if (this.min.size > this.max.size) {
3636
this.max.add(this.min.remove());
3737
} else {
3838
this.min.add(this.max.remove());
@@ -47,12 +47,12 @@ class MedianHeap {
4747
findMedian() {
4848
let median;
4949

50-
if (this.max.size() === this.min.size()) {
50+
if (this.max.size === this.min.size) {
5151
// When both heaps contain the same number of elements,
5252
// the total number of elements is even.
5353
// The median is the mean of the two middle elements.
5454
median = (this.max.peek() + this.min.peek()) / 2;
55-
} else if (this.max.size() > this.min.size()) {
55+
} else if (this.max.size > this.min.size) {
5656
// when the max-heap contains one more element than the min-heap,
5757
// the median is in the top of the max-heap.
5858
median = this.max.peek();
@@ -67,8 +67,8 @@ class MedianHeap {
6767
/**
6868
* Return size of the heap.
6969
*/
70-
size() {
71-
return this.min.size() + this.max.size();
70+
getsize() {
71+
return this.min.size + this.max.size;
7272
}
7373
}
7474

‎src/data-structures/heaps/median-heap.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ describe('Median Heap', () => {
1010
describe('#add', () => {
1111
it('should work', () => {
1212
expect(medianHeap.add(1)).toEqual(undefined);
13-
expect(medianHeap.size()).toEqual(1);
13+
expect(medianHeap.size).toEqual(1);
1414
});
1515

1616
it('should work', () => {
1717
expect(medianHeap.add(1)).toEqual(undefined);
1818
expect(medianHeap.add(1)).toEqual(undefined);
19-
expect(medianHeap.size()).toEqual(2);
19+
expect(medianHeap.size).toEqual(2);
2020
});
2121
});
2222

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /