-
Notifications
You must be signed in to change notification settings - Fork 441
/
heap.js
119 lines (96 loc) · 3.92 KB
/
heap.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
HEAP SORT
*** Description
Heap sort consists of two parts:
1) Build a heap out of the data from the input array
2) Create sorted array by iteratively removing the largest element from the heap and inserting it into the sorted array
*** Exercise
Implement heap sort using the Heap constructor provided.
*** Extra Credit
Now try building heapsort from scratch, without using the Heap constructor. See if you can do everything in place.
(for hints see https://en.wikipedia.org/wiki/Heapsort#Algorithm)
Example:
Note that the array is separated into two portions -
heap|sorted
[ 7 2 5 1|8 9 10]
swap first value (max) with element at end of heap
[ 1 2 5 7|8 9 10]
heap size has decreased and sorted portion has now grown
[ 1 2 5|7 8 9 10]
heap portion is re-heapified so that the first value is the new max
[ 5 1 2|7 8 9 10]
heap|sorted
repeat...
*/
var Heap = function() {
this.storage = [];
};
Heap.prototype.insert = function(value) {
// Push to storage array
this.storage.push(value);
var that = this;
// Recursive function to handle swaps, input index
var reheapify = function(index) {
// Get parent index
var parentInd = Math.ceil(index/2-1);
// Base Case : value < parent or parent is null
if (parentInd < 0 || that.storage[index] <= that.storage[parentInd]) {
return 'value added to index '+index;
}
// Recursive Case: swap with parent and make recursive call
var temp = that.storage[index];
that.storage[index] = that.storage[parentInd];
that.storage[parentInd] = temp;
return reheapify(parentInd);
};
return reheapify(that.storage.length-1);
};
// Heap remove max method on prototype
// Remove the max value from a heap, reorder the heap, and return the max value
Heap.prototype.removeMax = function() {
// Check if heap is currently empty
if (this.storage.length === 0) {
// If nothing to remove then return null
return null;
} else if (this.storage.length === 1) {
// If heap only has one element in it then pop off the lone element in the storage array and return it
var removed = this.storage.pop();
return removed;
}
// Handle all other cases where heap has more than one node
// Preserve the max value in order to return it
var maxValue = this.storage[0];
// Replace the root node with the last node of the heap and remove the last node
this.storage[0] = this.storage.pop();
// Preserve context for inner recursive helper function
var that = this;
// Recursive function to restore the heap property of the heap
var reheapify = function(index) {
// Set index of max value to current node's index
var maxIndex = index;
// Check first child node's value against current node
if ((2*index + 1 < that.storage.length) && (that.storage[2*index + 1] > that.storage[index])) {
// If greater then set index of max value to first child node's index
maxIndex = 2*index + 1;
}
// Check second child node's value against current max node
if ((2*index + 2 < that.storage.length) && (that.storage[2*index + 2] > that.storage[maxIndex])) {
// If greater then set index of max value to second child node's index
maxIndex = 2*index + 2;
}
// If the index of the max value is not equal to the index of the current node
// Then swap the nodes and reheapify at the new index of the current node
if (maxIndex !== index) {
// Swap node values (here's a nifty way to do so "in place" using the XOR bitwise operator)
that.storage[index] = that.storage[index] ^ that.storage[maxIndex];
that.storage[maxIndex] = that.storage[index] ^ that.storage[maxIndex];
that.storage[index] = that.storage[index] ^ that.storage[maxIndex];
// Reheapify at new index of current node
reheapify(maxIndex);
}
};
// Recursively move the swapped node down the heap until it's greater than both of its children
reheapify(0);
// Return the removed max value from the heap
return maxValue;
};