-
Notifications
You must be signed in to change notification settings - Fork 69
Expand file tree
/
Copy pathHeap.js
More file actions
122 lines (113 loc) · 2.7 KB
/
Copy pathHeap.js
File metadata and controls
122 lines (113 loc) · 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
class Heap {
/**
* Constructor for Heap data structure.
*
* This is a max Heap supported by an Array. This can be modified into a min Heap
* by swapping the item comparisons. The Heap is intended for Number items, but can be
* modified for any item.
*
* @class
*
* @param {Number} i1
* @param {Number} i2
* @returns {void}
*/
constructor() {
Object.defineProperty(this, '_storage', {
value: new Array(1)
});
}
/**
* Returns number of items in Heap.
*
* @returns {Number}
*/
get length() {
return this._storage.length-1;
}
/**
* Swaps items.
*
* @param {Number} i1
* @param {Number} i2
* @returns {void}
*/
_swap(i1, i2) {
[this._storage[i1], this._storage[i2]] = [this._storage[i2], this._storage[i1]];
}
/**
* Moves item up the heap to the correct position.
*
* @param {Number} index
* @returns {void}
*/
_rise(index) {
if (index === 1) { return; } // base case: top item
const parentIndex = Math.floor(index/2); // child items are 2*index and 2*index + 1
// swap if < for max heap, > for min heap
if (this._storage[parentIndex] < this._storage[index]) {
this._swap(parentIndex, index);
this._rise(parentIndex);
}
}
/**
* Moves item down the heap to the correct position.
*
* @param {Number} index
* @returns {void}
*/
_fall(index) {
if (2*index >= this._storage.length) { return; } // base case: no children
const childIndex = 2*index+1 >= this._storage.length ?
2*index // one child (left)
: this._storage[2*index] > this._storage[2*index+1] ? // two children
2*index
: 2*index+1; // compare with largest child
if (this._storage[childIndex] > this._storage[index]) {
this._swap(childIndex, index);
this._fall(childIndex);
}
}
/**
* Returns true if there are no items in the Heap, otherwise false.
*
* @returns {Boolean}
*/
isEmpty() {
return this._storage.length === 1;
}
/**
* Returns the top item in Heap.
*
* If the Heap is empty, returns undefined.
*
* @returns {Number}
*/
peek() {
return this._storage[1];
}
/**
* Returns and removes the top item in Heap.
*
* If the Heap is empty, returns undefined.
*
* @returns {Number}
*/
getMax() {
if (this.isEmpty()) { return; }
this._swap(1, this._storage.length-1); // swap top item and last item
const top = this._storage.pop();
this._fall(1);
return top;
}
/**
* Adds an item to the Heap.
*
* @returns {void}
*/
push(item) {
this._storage.push(item);
this._rise(this._storage.length-1);
}
}
module.exports = Heap;