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 874f3eb

Browse files
✨ feat (heap): Add Heap implementation (PriorityQueue) (amejiarosario#51)
1 parent 64a4a4f commit 874f3eb

File tree

3 files changed

+209
-0
lines changed

3 files changed

+209
-0
lines changed

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
class Heap {
2+
constructor(comparator = (a, b) => a - b) {
3+
this.array = [];
4+
this.comparator = (i1, i2) => comparator(this.array[i1], this.array[i2]);
5+
}
6+
7+
add(value) {
8+
this.array.push(value);
9+
this.bubbleUp();
10+
}
11+
12+
peek() {
13+
return this.array[0];
14+
}
15+
16+
remove() {
17+
this.swap(0, this.size() - 1);
18+
const value = this.array.pop();
19+
this.bubbleDown();
20+
return value;
21+
}
22+
23+
size() {
24+
return this.array.length;
25+
}
26+
27+
bubbleUp() {
28+
let index = this.size() - 1;
29+
const parent = (i) => Math.ceil(i / 2 - 1);
30+
while (parent(index) >= 0 && this.comparator(parent(index), index) > 0) {
31+
this.swap(parent(index), index);
32+
index = parent(index);
33+
}
34+
}
35+
36+
bubbleDown() {
37+
let index = 0;
38+
const left = (i) => 2 * i + 1;
39+
const right = (i) => 2 * i + 2;
40+
const getTopChild = (i) => (right(i) < this.size()
41+
&& this.comparator(left(i), right(i)) > 0 ? right(i) : left(i));
42+
43+
while (left(index) < this.size() && this.comparator(index, getTopChild(index)) > 0) {
44+
const next = getTopChild(index);
45+
this.swap(index, next);
46+
index = next;
47+
}
48+
}
49+
50+
swap(i1, i2) {
51+
[this.array[i1], this.array[i2]] = [this.array[i2], this.array[i1]];
52+
}
53+
}
54+
55+
module.exports = Heap;

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

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
const Heap = require('./heap');
2+
3+
describe('Min-Heap (Priority Queue)', () => {
4+
let heap;
5+
6+
beforeEach(() => {
7+
heap = new Heap();
8+
});
9+
10+
describe('#contructor', () => {
11+
it('should initialize', () => {
12+
expect(heap).not.toBe(undefined);
13+
});
14+
});
15+
16+
describe('#add', () => {
17+
it('should add an element', () => {
18+
expect(heap.add(1)).toBe(undefined);
19+
expect(heap.array).toEqual([1]);
20+
expect(heap.size()).toBe(1);
21+
});
22+
23+
it('should keep things in order', () => {
24+
heap.add(3);
25+
expect(heap.array[0]).toEqual(3);
26+
heap.add(2);
27+
expect(heap.array[0]).toEqual(2);
28+
heap.add(1);
29+
expect(heap.array[0]).toEqual(1);
30+
expect(heap.size()).toEqual(3);
31+
});
32+
});
33+
34+
describe('#remove', () => {
35+
it('should work', () => {
36+
heap.add(1);
37+
heap.add(0);
38+
expect(heap.remove()).toBe(0);
39+
expect(heap.size()).toBe(1);
40+
expect(heap.array).toEqual([1]);
41+
});
42+
});
43+
44+
describe('when has elements', () => {
45+
beforeEach(() => {
46+
heap.add(1);
47+
heap.add(2);
48+
heap.add(3);
49+
heap.add(0);
50+
});
51+
52+
describe('#peek', () => {
53+
it('should get min', () => {
54+
expect(heap.peek()).toEqual(0);
55+
});
56+
});
57+
58+
describe('#remove', () => {
59+
it('should get min', () => {
60+
expect(heap.remove()).toEqual(0);
61+
expect(heap.remove()).toEqual(1);
62+
expect(heap.remove()).toEqual(2);
63+
expect(heap.remove()).toEqual(3);
64+
expect(heap.size()).toBe(0);
65+
});
66+
});
67+
});
68+
});
69+
70+
describe('Max-Heap (Priority Queue)', () => {
71+
let heap;
72+
73+
beforeEach(() => {
74+
heap = new Heap((a, b) => b - a);
75+
});
76+
77+
describe('#contructor', () => {
78+
it('should initialize', () => {
79+
expect(heap).not.toBe(undefined);
80+
});
81+
});
82+
83+
describe('#add', () => {
84+
it('should add an element', () => {
85+
expect(heap.add(1)).toBe(undefined);
86+
expect(heap.array).toEqual([1]);
87+
expect(heap.size()).toBe(1);
88+
});
89+
90+
it('should keep things in order', () => {
91+
heap.add(1);
92+
expect(heap.array[0]).toEqual(1);
93+
heap.add(2);
94+
expect(heap.array[0]).toEqual(2);
95+
heap.add(3);
96+
expect(heap.array[0]).toEqual(3);
97+
expect(heap.size()).toEqual(3);
98+
});
99+
});
100+
101+
describe('#remove', () => {
102+
it('should work', () => {
103+
heap.add(1);
104+
heap.add(0);
105+
expect(heap.remove()).toBe(1);
106+
expect(heap.size()).toBe(1);
107+
expect(heap.array).toEqual([0]);
108+
});
109+
110+
it('should work with duplicates', () => {
111+
heap.add(3);
112+
heap.add(2);
113+
heap.add(3);
114+
heap.add(1);
115+
heap.add(2);
116+
heap.add(4);
117+
heap.add(5);
118+
heap.add(5);
119+
heap.add(6);
120+
121+
expect(heap.remove()).toEqual(6);
122+
expect(heap.remove()).toEqual(5);
123+
expect(heap.remove()).toEqual(5);
124+
expect(heap.remove()).toEqual(4);
125+
});
126+
});
127+
128+
describe('when has elements', () => {
129+
beforeEach(() => {
130+
heap.add(1);
131+
heap.add(2);
132+
heap.add(3);
133+
heap.add(0);
134+
});
135+
136+
describe('#peek', () => {
137+
it('should get min', () => {
138+
expect(heap.peek()).toEqual(3);
139+
});
140+
});
141+
142+
describe('#remove', () => {
143+
it('should get min when duplicates', () => {
144+
expect(heap.remove()).toEqual(3);
145+
expect(heap.remove()).toEqual(2);
146+
expect(heap.remove()).toEqual(1);
147+
expect(heap.remove()).toEqual(0);
148+
expect(heap.size()).toBe(0);
149+
});
150+
});
151+
});
152+
});

‎src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const AvlTree = require('./data-structures/trees/avl-tree');
1515
const RedBlackTree = require('./data-structures/trees/red-black-tree');
1616
const LRUCache = require('./data-structures/custom/lru-cache');
1717
const Trie = require('./data-structures/trees/trie');
18+
const Heap = require('./data-structures/trees/heap');
1819

1920
// algorithms
2021
const bubbleSort = require('./algorithms/sorting/bubble-sort');
@@ -40,6 +41,7 @@ module.exports = {
4041
RedBlackTree,
4142
LRUCache,
4243
Trie,
44+
Heap,
4345
bubbleSort,
4446
insertionSort,
4547
selectionSort,

0 commit comments

Comments
(0)

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