-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMaxHeap.js
102 lines (84 loc) · 2.49 KB
/
MaxHeap.js
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
class MaxHeap {
this.items = [];
constructor(){}
pop(){
if(this.items.length === 0) return;
//remove the root element
var val = this.items[0];
//move this.item[size-1] to the root;
this.items[0] = this.items[this.items.length-1];
this.items.splice(this.items.length-1, 1);
//move down the root value untill it hits the right place
_heapifyDown();
return val;
}
peek(){
return this.items[0];
}
insert(item){
//push the item
this.add(item);
_heapifyUp();
}
getSize(){
return this.items.length;
}
//internal methods (ES6 doesn't have "private")
_hasLeftChild(i){ return (_leftChild(i) !== undefined); }
_hasRightChild(i){ return (_rightChild(i) !== undefined); }
_hasParent(i){ return (i !== 0); }
_root(i){ return this.items[i]; }
_leftChild(i){ return this.items[_leftChildIndex(i)]; }
_rightChild(i){ return this.items[_rightChildIndex(i)]; }
_parent(i){ return this.items[_parentIndex(i)]; }
_leftChildIndex(i){ return 2 * i + 1; }
_rightChildIndex(i){ return 2 * i + 2; }
_parentIndex(i) { return Math.ceil((i - 2) / 2); }
_swap(i, j){
var temp = this.items[i];
this.items[i] = this.items[j];
this.items[j] = temp;
}
_hasBiggerLeftChild(i){
return (_hasLeftChild(i) && (_root(i) < _leftChild(i));
}
_hasBiggerRightChild(i){
return (_hasRightChild(i) && (_root(i) < _rightChild(i));
}
_hasBiggerParent(i){
return (_hasParent(i) && (_root(i) < _parent(i));
}
//check if the item is in the right place
//if true or the item is at the top, stop it,
//if false, bubble it up to its parent
_heapifyUp(){
var i = this.items.length-1;
//end if its parent isn't bigger than the root OR it has no parent
while(!_hasBiggerParent(i)){
swap(i, _parentIndex(i));
}
}
//check the root.
//if it's not the biggest value, move it down to the right position.
_heapifyDown(){
var i = 0;
//end if it has no child which is bigger than the root
while(_hasBiggerLeftChild(i) || _hasBiggerRightChild(i)) {
if(!_hasRightChild(i)){
//if it doesn't have its right child, _hasBiggerLeftChild(i) must be true.
//Swap the root with its left child.
var leftChildIndex = _leftChildIndex(i)
swap(i, leftChildIndex);
i = leftChildIndex;
}else{
//If it has both children, choose the bigger one
var L = _leftChild(i);
var R = _rightChild(i);
var biggerChildIndex = (L > R) ? _leftChildIndex(i) : _rightChildIndex(i);
//Swap it with the bigger one.
swap(i, biggerChildIndex);
i = biggerChildIndex;
}
}
}
}