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