1
1
export interface KeyVal < V , K > {
2
2
key ?: K ,
3
- val : V
3
+ val : V ,
4
+ leftOrRight ?: 'left' | 'right'
4
5
}
5
6
6
- class Node < V , K > {
7
+ export interface NumericCompare {
8
+
9
+ }
10
+
11
+ const emptyNodeSymbol = Symbol ( 'empty.node' ) ;
12
+
13
+ class SortedQueueNode < V , K > {
7
14
key : K ;
8
15
val : V ;
9
- left : Node < V , K > = null ;
10
- right : Node < V , K > = null ;
16
+ parent : SortedQueueNode < V , K > = null ;
17
+ left : SortedQueueNode < V , K > = null ;
18
+ right : SortedQueueNode < V , K > = null ;
19
+ leftOrRight : 'left' | 'right' = null ;
11
20
12
- constructor ( { key, val} : KeyVal < V , K > , left ?: Node < V , K > , right ?: Node < V , K > ) {
21
+ constructor ( { key, val, leftOrRight } : KeyVal < V , K > , left ?: SortedQueueNode < V , K > | Symbol , right ?: SortedQueueNode < V , K > | Symbol ) {
13
22
this . val = val ;
14
23
this . key = key ;
15
24
if ( arguments . length > 2 ) {
16
- if ( ! ( left && left instanceof Node ) ) {
17
- throw new Error ( 'Argument for left node, should be instance of Node.' )
25
+ if ( left !== emptyNodeSymbol ) {
26
+ if ( ! ( left && left instanceof SortedQueueNode ) ) {
27
+ throw new Error ( 'Argument for left node, should be instance of Node.' )
28
+ }
29
+ this . left = left ;
30
+ this . left . parent = this ;
18
31
}
32
+
19
33
}
20
34
if ( arguments . length > 3 ) {
21
- if ( ! ( right && right instanceof Node ) ) {
22
- throw new Error ( 'argument for right node, should be instance of Node.' )
35
+ if ( right !== emptyNodeSymbol ) {
36
+ if ( ! ( right && right instanceof SortedQueueNode ) ) {
37
+ throw new Error ( 'argument for right node, should be instance of Node.' )
38
+ }
39
+ this . right = right ;
40
+ this . right . parent = this ;
23
41
}
24
42
}
25
- this . left = left ;
26
- this . right = right ;
43
+
44
+
27
45
}
28
46
29
47
getValue ( ) {
@@ -38,12 +56,12 @@ export interface SortedQueueOpts<V, K> {
38
56
39
57
class SortedQueue < V , K = any > {
40
58
41
- rootNode : Node < V , K > = null ;
59
+ rootNode : SortedQueueNode < V , K > = null ;
42
60
compareByNum : SortedQueueOpts < V , K > [ 'compareByNum' ] ;
43
61
compareByBoolean : SortedQueueOpts < V , K > [ 'compareByBoolean' ] ;
44
62
map = new Map < K , V > ( ) ;
45
63
46
- constructor ( rootNodeVal : Node < V , K > , opts : SortedQueueOpts < V , K > ) {
64
+ constructor ( rootNodeVal : SortedQueueNode < V , K > , opts : SortedQueueOpts < V , K > ) {
47
65
this . rootNode = rootNodeVal ;
48
66
this . compareByNum = opts . compareByNum ;
49
67
this . compareByBoolean = opts . compareByBoolean ;
@@ -81,6 +99,56 @@ class SortedQueue<V, K = any> {
81
99
82
100
}
83
101
102
+ doLeftRotation ( n : SortedQueueNode < V , K > ) {
103
+
104
+ if ( ! n . left ) {
105
+ throw new Error ( 'missing left node' ) ;
106
+ }
107
+
108
+ if ( n . left . left ) {
109
+ throw new Error ( 'left.left should not be defined yet.' )
110
+ }
111
+
112
+ if ( n . left . right ) {
113
+ throw new Error ( 'left.right should not be defined yet.' )
114
+ }
115
+
116
+ if ( ! n . parent ) {
117
+ if ( ! ( ( n as any ) . isRoot ) ) {
118
+ throw new Error ( 'no parent?' )
119
+ }
120
+ return ;
121
+ }
122
+
123
+ const parentVal = n . parent . val ;
124
+ const halfVal = ( parentVal as any ) / 2 ;
125
+ const diffCurr = Math . abs ( ( n . val as any ) - ( halfVal as any ) ) ;
126
+ const diffPotential = Math . abs ( ( n . left . val as any ) - ( halfVal ) ) ;
127
+
128
+ console . log ( { diffCurr, diffPotential} ) ;
129
+
130
+ if ( diffPotential < diffCurr ) {
131
+ return ; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
132
+ // throw new Error('doing?')
133
+ const parent = n . parent ;
134
+ const right = n . right ;
135
+ const left = n . left ;
136
+ n . left = null ;
137
+ n . right = null ;
138
+ n . parent = left ;
139
+ left . parent = parent ;
140
+ left . right = right ;
141
+ left . left = n ;
142
+ parent . left = left ;
143
+
144
+ }
145
+
146
+ }
147
+
148
+ doRightRotation ( n : SortedQueueNode < V , K > ) {
149
+
150
+ }
151
+
84
152
find ( val : V ) {
85
153
86
154
let currentNode = this . rootNode ;
@@ -123,7 +191,7 @@ class SortedQueue<V, K = any> {
123
191
124
192
insert ( val : V , key ?: K ) {
125
193
126
- const newNode = new Node < V , K > ( { val, key} ) ;
194
+ const newNode = new SortedQueueNode < V , K > ( { val, key} ) ;
127
195
let currentNode = this . rootNode ;
128
196
129
197
let numOfSearches = 0 ;
@@ -137,7 +205,10 @@ class SortedQueue<V, K = any> {
137
205
if ( v <= 0 ) {
138
206
139
207
if ( ! currentNode . left ) {
208
+ newNode . parent = currentNode ;
140
209
currentNode . left = newNode ;
210
+ newNode . leftOrRight = 'left' ;
211
+ this . doLeftRotation ( currentNode ) ;
141
212
break ;
142
213
}
143
214
@@ -149,7 +220,10 @@ class SortedQueue<V, K = any> {
149
220
150
221
151
222
if ( ! currentNode . right ) {
223
+ newNode . parent = currentNode ;
152
224
currentNode . right = newNode ;
225
+ newNode . leftOrRight = 'right' ;
226
+ this . doRightRotation ( currentNode ) ;
153
227
break ;
154
228
}
155
229
@@ -159,61 +233,75 @@ class SortedQueue<V, K = any> {
159
233
160
234
}
161
235
162
- console . log ( { numOfSearches} ) ;
236
+ // console.log({numOfSearches});
163
237
164
238
}
165
239
166
240
167
- compareNodesByBoolean ( a : Node < V , K > , b : Node < V , K > ) {
241
+ compareNodesByBoolean ( a : SortedQueueNode < V , K > , b : SortedQueueNode < V , K > ) {
168
242
return this . compareByBoolean ( a . getValue ( ) , b . getValue ( ) )
169
243
}
170
244
171
245
}
172
246
247
+ const getNode = < V , K > ( v : number , count : number ) : SortedQueueNode < V , K > => {
248
+ // console.log(v, count);
249
+ return new SortedQueueNode < V , K > (
250
+ { val : v as any , key : v as any } ,
251
+ count > 19 ? emptyNodeSymbol : getNode ( v / 2 , count + 1 ) ,
252
+ count > 19 ? emptyNodeSymbol : getNode ( v * 3 / 2 , count + 1 ) ,
253
+ ) ;
254
+ }
173
255
174
- const rootNode = new Node < number , number > (
256
+ console . time ( 'foo' )
257
+ const rootNode = getNode ( 0.5 , 1 ) ;
258
+ ( rootNode as any ) . isRoot = true ;
259
+ console . timeEnd ( 'foo' ) ;
260
+ // process.exit(0);
261
+
262
+ const rootNode2 = new SortedQueueNode < number , number > (
175
263
{ val : 0.5 } ,
176
264
177
- new Node < number , number > (
265
+ new SortedQueueNode < number , number > (
178
266
{ val : 0.25 } ,
179
- new Node < number , number > (
267
+ new SortedQueueNode < number , number > (
180
268
{ val : 0.125 } ,
181
- new Node < number , number > (
269
+ new SortedQueueNode < number , number > (
182
270
{ val : 0.0625 } ,
183
271
) ,
184
- new Node < number , number > (
272
+ new SortedQueueNode < number , number > (
185
273
{ val : 0.1875 } ,
186
274
) ,
187
275
) ,
188
- new Node < number , number > (
276
+ new SortedQueueNode < number , number > (
189
277
{ val : 0.375 } ,
190
- new Node < number , number > (
278
+ new SortedQueueNode < number , number > (
191
279
{ val : 0.3125 } ,
192
280
) ,
193
- new Node < number , number > (
281
+ new SortedQueueNode < number , number > (
194
282
{ val : 0.4375 } ,
195
283
) ,
196
284
) ,
197
285
) ,
198
- new Node < number , number > (
286
+ new SortedQueueNode < number , number > (
199
287
{ val : 0.75 } ,
200
288
201
- new Node < number , number > (
289
+ new SortedQueueNode < number , number > (
202
290
{ val : 0.625 } ,
203
- new Node < number , number > (
291
+ new SortedQueueNode < number , number > (
204
292
{ val : 0.5625 } ,
205
293
) ,
206
- new Node < number , number > (
294
+ new SortedQueueNode < number , number > (
207
295
{ val : 0.6875 } ,
208
296
) ,
209
297
) ,
210
298
211
- new Node < number , number > (
299
+ new SortedQueueNode < number , number > (
212
300
{ val : 0.875 } ,
213
- new Node < number , number > (
301
+ new SortedQueueNode < number , number > (
214
302
{ val : 0.8125 } ,
215
303
) ,
216
- new Node < number , number > (
304
+ new SortedQueueNode < number , number > (
217
305
{ val : 0.9375 } ,
218
306
) ,
219
307
) ,
@@ -222,23 +310,23 @@ const rootNode = new Node<number, number>(
222
310
223
311
const sq = new SortedQueue ( rootNode , {
224
312
compareByBoolean : ( ( a , b ) => a > b ) ,
225
- compareByNum : ( ( a , b ) => a - b ) ,
313
+ compareByNum : ( ( a , b ) => ( a as number ) - ( b as number ) ) ,
226
314
} ) ;
227
315
228
316
const vals = [ ] ;
229
317
230
318
console . time ( 'start' ) ;
231
- for ( let i = 0 ; i < 100000 ; i ++ ) {
319
+ for ( let i = 0 ; i < 1000 ; i ++ ) {
232
320
const r = Math . random ( ) ;
233
- console . time ( String ( r ) ) ;
321
+ // console.time(String(r));
234
322
sq . insert ( r ) ;
235
- console . timeEnd ( String ( r ) ) ;
323
+ // console.timeEnd(String(r));
236
324
vals . push ( r ) ;
237
325
}
238
326
console . timeEnd ( 'start' ) ;
239
327
240
328
241
- const doRecurse = < K , V > ( n : Node < V , K > , count : number ) => {
329
+ const doRecurse = < K , V > ( n : SortedQueueNode < V , K > , count : number ) => {
242
330
243
331
if ( ! n ) {
244
332
return { numRight : count , numLeft : count } ;
@@ -255,8 +343,10 @@ const doRecurse = <K, V>(n: Node<V, K>, count: number) => {
255
343
numRight = doRecurse ( n . right , count + 1 ) . numRight ;
256
344
}
257
345
258
- if ( count < 50 ) {
259
- console . log ( { numLeft, numRight} ) ;
346
+ if ( count < 5 ) {
347
+ if ( true || numLeft !== numRight ) {
348
+ // console.log({numLeft, numRight});
349
+ }
260
350
}
261
351
262
352
return {
@@ -270,7 +360,7 @@ console.log(sq);
270
360
for ( const v of vals ) {
271
361
console . log ( sq . find ( v ) . numOfSearches ) ;
272
362
}
273
- // console.log(sq.find(0.375));
274
- // console.log(sq.find(0.8125));
275
- //
276
- // console.log(sq.findNextBiggest(0.11));
363
+ console . log ( sq . find ( 0.375 ) ) ;
364
+ console . log ( sq . find ( 0.8125 ) ) ;
365
+
366
+ console . log ( sq . findNextBiggest ( 0.11 ) ) ;
0 commit comments