MaxHeap [最大堆]
# 介绍
最大堆是一种特殊的堆,若母节点的值恒大于等于子节点的值,此堆称为最大堆(max heap)。
# 实现
# JavaScript
const { Heap } = require('./heap');
const getMaxCompare = (getCompareValue) => (a, b) => {
const aVal = typeof getCompareValue === 'function' ? getCompareValue(a) : a;
const bVal = typeof getCompareValue === 'function' ? getCompareValue(b) : b;
return aVal < bVal ? 1 : -1;
};
/**
* @class MaxHeap
* @extends Heap
*/
class MaxHeap {
/**
* @param {function} [getCompareValue]
* @param {Heap} [_heap]
*/
constructor(getCompareValue, _heap) {
this._getCompareValue = getCompareValue;
this._heap = _heap || new Heap(getMaxCompare(getCompareValue));
}
/**
* Inserts a new value into the heap
* @public
* @param {number|string|object} value
* @returns {MaxHeap}
*/
insert(value) {
return this._heap.insert(value);
}
/**
* Removes and returns the root node in the heap
* @public
* @returns {number|string|object}
*/
extractRoot() {
return this._heap.extractRoot();
}
/**
* Applies heap sort and return the values sorted by priority
* @public
* @returns {array}
*/
sort() {
return this._heap.sort();
}
/**
* Fixes node positions in the heap
* @public
* @returns {MaxHeap}
*/
fix() {
return this._heap.fix();
}
/**
* Verifies that all heap nodes are in the right position
* @public
* @returns {boolean}
*/
isValid() {
return this._heap.isValid();
}
/**
* Returns the root node in the heap
* @public
* @returns {number|string|object}
*/
root() {
return this._heap.root();
}
/**
* Returns a leaf node in the heap
* @public
* @returns {number|string|object}
*/
leaf() {
return this._heap.leaf();
}
/**
* Returns the number of nodes in the heap
* @public
* @returns {number}
*/
size() {
return this._heap.size();
}
/**
* Checks if the heap is empty
* @public
* @returns {boolean}
*/
isEmpty() {
return this._heap.isEmpty();
}
/**
* Clears the heap
* @public
*/
clear() {
this._heap.clear();
}
/**
* Returns a shallow copy of the MaxHeap
* @public
* @returns {MaxHeap}
*/
clone() {
return new MaxHeap(this._getCompareValue, this._heap.clone());
}
/**
* Builds a MaxHeap from an array
* @public
* @static
* @param {array} values
* @param {function} [getCompareValue]
* @returns {MaxHeap}
*/
static heapify(values, getCompareValue) {
if (!Array.isArray(values)) {
throw new Error('MaxHeap.heapify expects an array');
}
const heap = new Heap(getMaxCompare(getCompareValue), values);
return new MaxHeap(getCompareValue, heap).fix();
}
/**
* Checks if a list of values is a valid max heap
* @public
* @static
* @param {array} values
* @param {function} [getCompareValue]
* @returns {boolean}
*/
static isHeapified(values, getCompareValue) {
const heap = new Heap(getMaxCompare(getCompareValue), values);
return new MaxHeap(getCompareValue, heap).isValid();
}
}
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
或者:
class BinaryHeap {
constructor () {
this.heap = []
}
insert (value) {
this.heap.push(value)
this.heapify()
}
size () {
return this.heap.length
}
empty () {
return this.size() === 0
}
// using iterative approach to reorder the heap after insertion
heapify () {
let index = this.size() - 1
while (index > 0) {
const element = this.heap[index]
const parentIndex = Math.floor((index - 1) / 2)
const parent = this.heap[parentIndex]
if (parent[0] >= element[0]) break
this.heap[index] = parent
this.heap[parentIndex] = element
index = parentIndex
}
}
// Extracting the maximum element from the Heap
extractMax () {
const max = this.heap[0]
const tmp = this.heap.pop()
if (!this.empty()) {
this.heap[0] = tmp
this.sinkDown(0)
}
return max
}
// To restore the balance of the heap after extraction.
sinkDown (index) {
const left = 2 * index + 1
const right = 2 * index + 2
let largest = index
const length = this.size()
if (left < length && this.heap[left][0] > this.heap[largest][0]) {
largest = left
}
if (right < length && this.heap[right][0] > this.heap[largest][0]) {
largest = right
}
// swap
if (largest !== index) {
const tmp = this.heap[largest]
this.heap[largest] = this.heap[index]
this.heap[index] = tmp
this.sinkDown(largest)
}
}
}
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
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
编辑 (opens new window)
上次更新: 2022/10/11, 17:42:20