1
+ /**
2
+ * A heap is a complete binary tree
3
+ * In a complete binary tree each level is filled before lower levels are added
4
+ * Each level is filled from left to right
5
+ *
6
+ * In a (min|max) heap the value of every node is (less|greater) than that if its children
7
+ *
8
+ * The heap if often implemented using an array structure.
9
+ * In the array implementation, the relationship between a parent index and its two children
10
+ * are ((parentindex * 2) + 1) and ((parentindex * 2) + 2)
11
+ *
12
+ */
13
+
1
14
export abstract class Heap < T > {
2
- protected heap : T [ ] ;
15
+ private heap : T [ ] ;
16
+ // A comparison function. Returns true if a should be the parent of b.
17
+ private compare : ( a : any , b : any ) => boolean ;
3
18
4
- constructor ( elements : T [ ] = [ ] ) {
19
+ constructor ( elements : T [ ] = [ ] , compare : ( a : T , b : T ) => boolean ) {
5
20
this . heap = [ ] ;
21
+ this . compare = compare ;
6
22
for ( let element of elements ) {
7
23
this . insert ( element ) ;
8
24
}
@@ -14,19 +30,22 @@ export abstract class Heap<T> {
14
30
* In a minHeap the value at parentIndex should be smaller than the value at childIndex
15
31
*
16
32
*/
17
- protected abstract isRightlyPlaced (
18
- childIndex : number ,
19
- parentIndex : number
20
- ) : boolean ;
33
+ private isRightlyPlaced ( childIndex : number , parentIndex : number ) {
34
+ return this . compare ( this . heap [ parentIndex ] , this . heap [ childIndex ] ) ;
35
+ }
21
36
22
37
/**
23
38
* In a maxHeap the index with the larger value is returned
24
39
* In a minHeap the index with the smaller value is returned
25
40
*/
26
- protected abstract getChildIndexToSwap (
27
- leftChildIndex : number ,
28
- rightChildIndex : number
29
- ) : number ;
41
+ private getChildIndexToSwap ( leftChildIndex : number , rightChildIndex : number ) : number {
42
+ if ( rightChildIndex >= this . size ( ) ) {
43
+ return leftChildIndex ;
44
+ }
45
+ return this . compare ( this . heap [ leftChildIndex ] , this . heap [ rightChildIndex ] )
46
+ ? leftChildIndex
47
+ : rightChildIndex ;
48
+ }
30
49
31
50
public insert ( value : T ) : void {
32
51
this . heap . push ( value ) ;
@@ -49,7 +68,7 @@ export abstract class Heap<T> {
49
68
return this . size ( ) === 0 ;
50
69
}
51
70
52
- protected bubbleUp ( ) : void {
71
+ private bubbleUp ( ) : void {
53
72
let index = this . size ( ) - 1 ;
54
73
let parentIndex ;
55
74
@@ -64,7 +83,7 @@ export abstract class Heap<T> {
64
83
}
65
84
}
66
85
67
- protected sinkDown ( ) : void {
86
+ private sinkDown ( ) : void {
68
87
let index = 0 ;
69
88
let leftChildIndex = this . getLeftChildIndex ( index ) ;
70
89
let rightChildIndex = this . getRightChildIndex ( index ) ;
@@ -86,19 +105,19 @@ export abstract class Heap<T> {
86
105
}
87
106
}
88
107
89
- protected getLeftChildIndex ( index : number ) : number {
108
+ private getLeftChildIndex ( index : number ) : number {
90
109
return index * 2 + 1 ;
91
110
}
92
111
93
- protected getRightChildIndex ( index : number ) : number {
112
+ private getRightChildIndex ( index : number ) : number {
94
113
return index * 2 + 2 ;
95
114
}
96
115
97
116
public check ( ) : void {
98
117
return this . _check ( ) ;
99
118
}
100
119
101
- protected _check ( index : number = 0 ) : void {
120
+ private _check ( index : number = 0 ) : void {
102
121
if ( ! this . heap [ index ] ) return ;
103
122
const leftChildIndex = this . getLeftChildIndex ( index ) ;
104
123
const rightChildIndex = this . getRightChildIndex ( index ) ;
@@ -119,3 +138,15 @@ export abstract class Heap<T> {
119
138
this . _check ( rightChildIndex ) ;
120
139
}
121
140
}
141
+
142
+ export class MinHeap < T > extends Heap < T > {
143
+ constructor ( elements : T [ ] = [ ] , compare = ( a : T , b : T ) => { return a < b } ) {
144
+ super ( elements , compare ) ;
145
+ }
146
+ }
147
+
148
+ export class MaxHeap < T > extends Heap < T > {
149
+ constructor ( elements : T [ ] = [ ] , compare = ( a : T , b : T ) => { return a > b } ) {
150
+ super ( elements , compare ) ;
151
+ }
152
+ }
0 commit comments