Skip to content

Commit 0d0918f

Browse files
committed
working on sorted queue
1 parent 429aa6b commit 0d0918f

File tree

1 file changed

+132
-42
lines changed

1 file changed

+132
-42
lines changed

src/sorted-queue.ts

Lines changed: 132 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,47 @@
11
export interface KeyVal<V, K> {
22
key?: K,
3-
val: V
3+
val: V,
4+
leftOrRight?: 'left' | 'right'
45
}
56

6-
class Node<V, K> {
7+
export interface NumericCompare {
8+
9+
}
10+
11+
const emptyNodeSymbol = Symbol('empty.node');
12+
13+
class SortedQueueNode<V, K> {
714
key: K;
815
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;
1120

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) {
1322
this.val = val;
1423
this.key = key;
1524
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;
1831
}
32+
1933
}
2034
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;
2341
}
2442
}
25-
this.left = left;
26-
this.right = right;
43+
44+
2745
}
2846

2947
getValue() {
@@ -38,12 +56,12 @@ export interface SortedQueueOpts<V, K> {
3856

3957
class SortedQueue<V, K = any> {
4058

41-
rootNode: Node<V, K> = null;
59+
rootNode: SortedQueueNode<V, K> = null;
4260
compareByNum: SortedQueueOpts<V, K>['compareByNum'];
4361
compareByBoolean: SortedQueueOpts<V, K>['compareByBoolean'];
4462
map = new Map<K, V>();
4563

46-
constructor(rootNodeVal: Node<V, K>, opts: SortedQueueOpts<V, K>) {
64+
constructor(rootNodeVal: SortedQueueNode<V, K>, opts: SortedQueueOpts<V, K>) {
4765
this.rootNode = rootNodeVal;
4866
this.compareByNum = opts.compareByNum;
4967
this.compareByBoolean = opts.compareByBoolean;
@@ -81,6 +99,56 @@ class SortedQueue<V, K = any> {
8199

82100
}
83101

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+
84152
find(val: V) {
85153

86154
let currentNode = this.rootNode;
@@ -123,7 +191,7 @@ class SortedQueue<V, K = any> {
123191

124192
insert(val: V, key?: K) {
125193

126-
const newNode = new Node<V, K>({val, key});
194+
const newNode = new SortedQueueNode<V, K>({val, key});
127195
let currentNode = this.rootNode;
128196

129197
let numOfSearches = 0;
@@ -137,7 +205,10 @@ class SortedQueue<V, K = any> {
137205
if (v <= 0) {
138206

139207
if (!currentNode.left) {
208+
newNode.parent = currentNode;
140209
currentNode.left = newNode;
210+
newNode.leftOrRight = 'left';
211+
this.doLeftRotation(currentNode);
141212
break;
142213
}
143214

@@ -149,7 +220,10 @@ class SortedQueue<V, K = any> {
149220

150221

151222
if (!currentNode.right) {
223+
newNode.parent = currentNode;
152224
currentNode.right = newNode;
225+
newNode.leftOrRight = 'right';
226+
this.doRightRotation(currentNode);
153227
break;
154228
}
155229

@@ -159,61 +233,75 @@ class SortedQueue<V, K = any> {
159233

160234
}
161235

162-
console.log({numOfSearches});
236+
// console.log({numOfSearches});
163237

164238
}
165239

166240

167-
compareNodesByBoolean(a: Node<V, K>, b: Node<V, K>) {
241+
compareNodesByBoolean(a: SortedQueueNode<V, K>, b: SortedQueueNode<V, K>) {
168242
return this.compareByBoolean(a.getValue(), b.getValue())
169243
}
170244

171245
}
172246

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+
}
173255

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>(
175263
{val: 0.5},
176264

177-
new Node<number, number>(
265+
new SortedQueueNode<number, number>(
178266
{val: 0.25},
179-
new Node<number, number>(
267+
new SortedQueueNode<number, number>(
180268
{val: 0.125},
181-
new Node<number, number>(
269+
new SortedQueueNode<number, number>(
182270
{val: 0.0625},
183271
),
184-
new Node<number, number>(
272+
new SortedQueueNode<number, number>(
185273
{val: 0.1875},
186274
),
187275
),
188-
new Node<number, number>(
276+
new SortedQueueNode<number, number>(
189277
{val: 0.375},
190-
new Node<number, number>(
278+
new SortedQueueNode<number, number>(
191279
{val: 0.3125},
192280
),
193-
new Node<number, number>(
281+
new SortedQueueNode<number, number>(
194282
{val: 0.4375},
195283
),
196284
),
197285
),
198-
new Node<number, number>(
286+
new SortedQueueNode<number, number>(
199287
{val: 0.75},
200288

201-
new Node<number, number>(
289+
new SortedQueueNode<number, number>(
202290
{val: 0.625},
203-
new Node<number, number>(
291+
new SortedQueueNode<number, number>(
204292
{val: 0.5625},
205293
),
206-
new Node<number, number>(
294+
new SortedQueueNode<number, number>(
207295
{val: 0.6875},
208296
),
209297
),
210298

211-
new Node<number, number>(
299+
new SortedQueueNode<number, number>(
212300
{val: 0.875},
213-
new Node<number, number>(
301+
new SortedQueueNode<number, number>(
214302
{val: 0.8125},
215303
),
216-
new Node<number, number>(
304+
new SortedQueueNode<number, number>(
217305
{val: 0.9375},
218306
),
219307
),
@@ -222,23 +310,23 @@ const rootNode = new Node<number, number>(
222310

223311
const sq = new SortedQueue(rootNode, {
224312
compareByBoolean: ((a, b) => a > b),
225-
compareByNum: ((a, b) => a - b),
313+
compareByNum: ((a, b) => (a as number) - (b as number)),
226314
});
227315

228316
const vals = [];
229317

230318
console.time('start');
231-
for (let i = 0; i < 100000; i++) {
319+
for (let i = 0; i < 1000; i++) {
232320
const r = Math.random();
233-
console.time(String(r));
321+
// console.time(String(r));
234322
sq.insert(r);
235-
console.timeEnd(String(r));
323+
// console.timeEnd(String(r));
236324
vals.push(r);
237325
}
238326
console.timeEnd('start');
239327

240328

241-
const doRecurse = <K, V>(n: Node<V, K>, count: number) => {
329+
const doRecurse = <K, V>(n: SortedQueueNode<V, K>, count: number) => {
242330

243331
if (!n) {
244332
return {numRight: count, numLeft: count};
@@ -255,8 +343,10 @@ const doRecurse = <K, V>(n: Node<V, K>, count: number) => {
255343
numRight = doRecurse(n.right, count + 1).numRight;
256344
}
257345

258-
if (count < 50) {
259-
console.log({numLeft, numRight});
346+
if (count < 5) {
347+
if (true || numLeft !== numRight) {
348+
// console.log({numLeft, numRight});
349+
}
260350
}
261351

262352
return {
@@ -270,7 +360,7 @@ console.log(sq);
270360
for (const v of vals) {
271361
console.log(sq.find(v).numOfSearches);
272362
}
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

Comments
 (0)