1
+ // src/11-heap/heap.js
2
+
3
+ const Comparator = require ( '../10-tree/comparator' ) ;
4
+
5
+ class Heap {
6
+ #heap = [ ] ;
7
+ #compareFn;
8
+
9
+ constructor ( compareFn = Comparator . defaultCompareFn ) {
10
+ this . #compareFn = new Comparator ( compareFn ) ;
11
+ }
12
+
13
+ getLeftChildIndex ( parentIndex ) {
14
+ return 2 * parentIndex + 1 ;
15
+ }
16
+
17
+ getRightChildIndex ( parentIndex ) {
18
+ return 2 * parentIndex + 2 ;
19
+ }
20
+
21
+ getParentIndex ( childIndex ) {
22
+ if ( childIndex === 0 ) { return undefined ; }
23
+ return Math . floor ( ( childIndex - 1 ) / 2 ) ;
24
+ }
25
+
26
+ insert ( value ) {
27
+ if ( value ) {
28
+ const index = this . #heap. length ;
29
+ this . #heap. push ( value ) ;
30
+ this . #siftUp( index ) ;
31
+ return true ;
32
+ }
33
+ return false ;
34
+ }
35
+
36
+ #siftUp( index ) {
37
+ const parentIndex = this . getParentIndex ( index ) ;
38
+
39
+ if ( parentIndex !== undefined && parentIndex >= 0 &&
40
+ this . #compareFn. greaterThan ( this . #heap[ parentIndex ] , this . #heap[ index ] )
41
+ ) {
42
+ [ this . #heap[ parentIndex ] , this . #heap[ index ] ] = [ this . #heap[ index ] , this . #heap[ parentIndex ] ] ;
43
+ this . #siftUp( parentIndex ) ;
44
+ }
45
+ }
46
+
47
+ extract ( ) {
48
+ if ( this . #heap. length === 0 ) {
49
+ return undefined ;
50
+ }
51
+
52
+ if ( this . #heap. length === 1 ) {
53
+ return this . #heap. shift ( ) ;
54
+ }
55
+
56
+ const root = this . #heap[ 0 ] ;
57
+ this . #heap[ 0 ] = this . #heap. pop ( ) ;
58
+ this . #siftDown( 0 ) ;
59
+ return root ;
60
+ }
61
+
62
+ #siftDown( index ) {
63
+ const leftIndex = this . getLeftChildIndex ( index ) ;
64
+ const rightIndex = this . getRightChildIndex ( index ) ;
65
+ let smallerIndex = index ;
66
+
67
+ if ( leftIndex < this . #heap. length &&
68
+ this . #compareFn. lessThan ( this . #heap[ leftIndex ] , this . #heap[ smallerIndex ] )
69
+ ) {
70
+ smallerIndex = leftIndex ;
71
+ }
72
+
73
+ if ( rightIndex < this . #heap. length &&
74
+ this . #compareFn. lessThan ( this . #heap[ rightIndex ] , this . #heap[ smallerIndex ] )
75
+ ) {
76
+ smallerIndex = rightIndex ;
77
+ }
78
+
79
+ if ( smallerIndex !== index ) {
80
+ [ this . #heap[ index ] , this . #heap[ smallerIndex ] ] = [ this . #heap[ smallerIndex ] , this . #heap[ index ] ] ;
81
+ this . #siftDown( smallerIndex ) ;
82
+ }
83
+ }
84
+
85
+ heapify ( array ) {
86
+ this . #heap = array ;
87
+ const lastParentIndex = this . getParentIndex ( this . #heap. length - 1 ) ;
88
+ if ( lastParentIndex !== undefined ) {
89
+ for ( let i = lastParentIndex ; i >= 0 ; i -- ) {
90
+ this . #siftDown( i ) ;
91
+ }
92
+ }
93
+ }
94
+
95
+ peek ( ) {
96
+ return this . #heap. length === 0 ? undefined : this . #heap[ 0 ] ;
97
+ }
98
+
99
+ get size ( ) {
100
+ return this . #heap. length ;
101
+ }
102
+
103
+ isEmpty ( ) {
104
+ return this . #heap. length === 0 ;
105
+ }
106
+
107
+ toArray ( ) {
108
+ return this . #heap. slice ( ) ;
109
+ }
110
+
111
+ clear ( ) {
112
+ this . #heap = [ ] ;
113
+ }
114
+
115
+ toString ( ) {
116
+ return this . #heap. toString ( ) ;
117
+ }
118
+ }
119
+
120
+ module . exports = Heap ;
0 commit comments