Skip to content

Commit f83c3aa

Browse files
committed
msort_list_td good enough for a prototype
1 parent a415b3f commit f83c3aa

File tree

5 files changed

+246
-54
lines changed

5 files changed

+246
-54
lines changed

src/algorithms/controllers/msort_lista_td.js

Lines changed: 224 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
1-
// Merge sort for lists (represented using array), top down
2-
// Prototype for pointer version. Adapted code from array version.
3-
// XXX Could do with a good clean up!
4-
// Lots of crud - may include some quicksort remnants also; probably
5-
// should have cleaned up mergesort array code before copying it...
6-
// Uses simple stack display like DFSrec
1+
// This comment is entirely for the
2+
// amusement of the person who wrote
3+
// it and should be ignored by anyone
4+
// else. However, THE COMMENTS BELOW
5+
// SHOULD BE READ BY ANYONE LOOKING
6+
// AT THE CODE, PARTICULARLY IF IT IS
7+
// TO BE MODIFIED!
8+
9+
// Animation of merge sort for lists (represented using array), top down.
10+
// XXX PROTOTYPE for pointer version. Adapted from code for mergesort for
11+
// arrays (may include some quicksort remnants also).
12+
// XXX Needs major clean up of code to remove junk, refactor, etc before
13+
// being used for anything else
14+
// XXX Not all steps are animated
15+
// XXX should be more consistent with mergesort for arrays with colours
16+
// etc
17+
// XXX Colours are very limited - colour support is a mystery to me and
18+
// there are major inconsistencies between colours specification for
19+
// graph nodes/edges, 1D arrays and 2D arrays (there is a student group
20+
// that will hopefully look into this and improve things)
721

822
import { msort_lista_td } from '../explanations';
923

@@ -155,7 +169,8 @@ const unhighlightB = (vis, index, isPrimaryColor = true) => {
155169
export function initVisualisers() {
156170
return {
157171
array: {
158-
instance: new Array2DTracer('array', null, 'Array representation of lists'),
172+
instance: new Array2DTracer('array', null,
173+
'Array representation of lists (PROTOTYPE FOR POINTER REPRESENTATION)'),
159174
order: 0,
160175
},
161176
}
@@ -184,6 +199,14 @@ export function run_msort() {
184199
// Define helper functions
185200
// ----------------------------------------------------------------------------------------------------------------------------
186201

202+
function assignMaybeNullVar(vis, variable_name, index) {
203+
if (index === 'Null') {
204+
vis.array.assignVariable(variable_name, 2, undefined);
205+
vis.array.assignVariable(variable_name+'=Null', 2, 0);
206+
} else
207+
vis.array.assignVariable(variable_name, 2, index);
208+
}
209+
187210
function assignVarToA(vis, variable_name, index) {
188211
if (index === undefined)
189212
vis.array.removeVariable(variable_name);
@@ -247,7 +270,13 @@ export function run_msort() {
247270

248271
chunker.add('Main', (vis, Lists, cur_L, cur_len, cur_depth, c_stk) => {
249272
vis.array.set(Lists, 'msort_lista_td');
250-
vis.array.assignVariable('L', 2, cur_L);
273+
vis.array.assignVariable('L', 2, cur_L);
274+
// colour all of R list
275+
let Tails = Lists[2];
276+
for (let i = cur_L; i !== 'Null'; i = Tails[i]) {
277+
vis.array.select(1, i, 1, i, '0');
278+
vis.array.select(2, i, 2, i, '0');
279+
}
251280
// if (cur_depth === 0) {
252281
// }
253282
// for (let i = cur_left; i <= cur_right; i++) {
@@ -289,17 +318,22 @@ cur_R, c_stk) => {
289318
vis.array.assignVariable('L', 2, cur_L);
290319
vis.array.assignVariable('Mid', 2, cur_Mid);
291320
vis.array.assignVariable('R', 2, cur_R);
321+
vis.array.select(1, cur_L, 1, cur_L, '0');
322+
vis.array.select(2, cur_L, 2, cur_L, '0');
323+
vis.array.select(1, cur_R, 1, cur_R, '0');
324+
vis.array.select(2, cur_R, 2, cur_R, '0');
292325
}, [[Indices, Heads, Tails], L, Mid, R, simple_stack], depth);
293326

294327
// dummy chunk for before recursive call - we need this so there
295328
// is a chunk at this recursion level as the first chunk in the
296329
// collapsed code for the recursive call
297-
chunker.add('preSortL', (vis, Lists, cur_L, cur_Mid, cur_R) => {
298-
// vis.array.set(Lists, 'msort_lista_td');
299-
// set_simple_stack(vis.array, c_stk);
300-
vis.array.assignVariable('Mid', 2, undefined);
301-
vis.array.assignVariable('R', 2, undefined);
302-
}, [[Indices, Heads, Tails], L, Mid, R], depth);
330+
chunker.add('preSortL', (vis, Lists, cur_L, cur_Mid, cur_R, c_stk) => {
331+
vis.array.set(Lists, 'msort_lista_td');
332+
set_simple_stack(vis.array, c_stk);
333+
vis.array.assignVariable('L', 2, cur_L);
334+
vis.array.select(1, cur_L, 1, cur_L, '0');
335+
vis.array.select(2, cur_L, 2, cur_L, '0');
336+
}, [[Indices, Heads, Tails], L, Mid, R, simple_stack], depth);
303337

304338

305339
L = MergeSort(L, midNum, depth + 1);
@@ -312,6 +346,14 @@ cur_R, c_stk) => {
312346
set_simple_stack(vis.array, c_stk);
313347
vis.array.assignVariable('L', 2, cur_L);
314348
vis.array.assignVariable('R', 2, cur_R);
349+
// colour all of L list
350+
let Tails = Lists[2];
351+
for (let i = cur_L; i !== 'Null'; i = Tails[i]) {
352+
vis.array.select(1, i, 1, i, '1');
353+
vis.array.select(2, i, 2, i, '1');
354+
}
355+
vis.array.select(1, cur_R, 1, cur_R, '0');
356+
vis.array.select(2, cur_R, 2, cur_R, '0');
315357
// for (let i = cur_left; i <= cur_mid; i++) {
316358
// unhighlight(vis, i, true);
317359
// highlight(vis, i, false)
@@ -322,14 +364,20 @@ cur_R, c_stk) => {
322364
}, [[Indices, Heads, Tails], L, R, Mid, simple_stack], depth);
323365

324366
// dummy chunk before recursive call, as above
325-
chunker.add('preSortR', (vis, a, cur_L, cur_Mid, cur_R) => {
326-
// vis.array.set(a, 'msort_lista_td');
327-
// for (let i = cur_left; i <= cur_mid; i++) {
328-
// unhighlight(vis, i, false);
329-
// }
330-
vis.array.assignVariable('L', 2, undefined);
367+
chunker.add('preSortR', (vis, Lists, cur_L, cur_Mid, cur_R, c_stk) => {
368+
vis.array.set(Lists, 'msort_lista_td');
369+
set_simple_stack(vis.array, c_stk);
370+
// vis.array.assignVariable('L', 2, undefined);
331371
vis.array.assignVariable('R', 2, cur_R);
332-
}, [[Indices, Heads, Tails], L, Mid, R], depth);
372+
vis.array.select(1, cur_R, 1, cur_R, '0');
373+
vis.array.select(2, cur_R, 2, cur_R, '0');
374+
// colour all of R list
375+
// let Tails = Lists[2];
376+
// for (let i = cur_R; i !== 'Null'; i = Tails[i]) {
377+
// vis.array.select(1, i, 1, i, '1');
378+
// vis.array.select(2, i, 2, i, '1');
379+
// }
380+
}, [[Indices, Heads, Tails], L, Mid, R, simple_stack], depth);
333381

334382
R = MergeSort(R, len - midNum, depth + 1);
335383

@@ -341,6 +389,15 @@ c_stk) => {
341389
set_simple_stack(vis.array, c_stk);
342390
vis.array.assignVariable('L', 2, cur_L);
343391
vis.array.assignVariable('R', 2, cur_R);
392+
vis.array.select(1, cur_L, 1, cur_L, '0');
393+
vis.array.select(2, cur_L, 2, cur_L, '0');
394+
// colour all of R list
395+
let Tails = Lists[2];
396+
for (let i = cur_R; i !== 'Null'; i = Tails[i]) {
397+
vis.array.select(1, i, 1, i, '1');
398+
vis.array.select(2, i, 2, i, '1');
399+
}
400+
344401
// for (let i = cur_mid+1; i <= cur_right; i++) {
345402
// unhighlight(vis, i, true);
346403
// unhighlight(vis, i, false)
@@ -358,28 +415,160 @@ c_stk) => {
358415
}
359416
// scan through adding elements to the end of M
360417
let E = M;
418+
chunker.add('E', (vis, Lists, cur_L, cur_R, cur_M, cur_E, c_stk) => {
419+
vis.array.set(Lists, 'msort_lista_td');
420+
set_simple_stack(vis.array, c_stk);
421+
assignMaybeNullVar(vis, 'L', cur_L);
422+
assignMaybeNullVar(vis, 'R', cur_R);
423+
vis.array.assignVariable('M', 2, cur_M);
424+
vis.array.assignVariable('E', 2, cur_E);
425+
if (cur_L !== 'Null') {
426+
vis.array.select(1, cur_L, 1, cur_L, '0');
427+
vis.array.select(2, cur_L, 2, cur_L, '0');
428+
}
429+
if (cur_R !== 'Null') {
430+
vis.array.select(1, cur_R, 1, cur_R, '0');
431+
vis.array.select(2, cur_R, 2, cur_R, '0');
432+
}
433+
vis.array.select(1, cur_M, 1, cur_M, '1');
434+
vis.array.select(2, cur_M, 2, cur_M, '1');
435+
}, [[Indices, Heads, Tails], L, R, M, E, simple_stack], depth);
361436
while (L !== 'Null' && R !== 'Null') {
362-
if (Heads[L] <= Heads[R]) {
363-
Tails[E] = L;
364-
E = L;
365-
L = Tails[L];
366-
} else {
367-
Tails[E] = R;
368-
E = R;
369-
R = Tails[R];
437+
chunker.add('whileNotNull', (vis, Lists, cur_L, cur_R, cur_M, cur_E, c_stk) => {
438+
vis.array.set(Lists, 'msort_lista_td');
439+
set_simple_stack(vis.array, c_stk);
440+
assignMaybeNullVar(vis, 'L', cur_L);
441+
assignMaybeNullVar(vis, 'R', cur_R);
442+
vis.array.assignVariable('M', 2, cur_M);
443+
assignMaybeNullVar(vis, 'E', cur_E);
444+
if (cur_L !== 'Null') {
445+
vis.array.select(1, cur_L, 1, cur_L, '0');
446+
vis.array.select(2, cur_L, 2, cur_L, '0');
447+
}
448+
if (cur_R !== 'Null') {
449+
vis.array.select(1, cur_R, 1, cur_R, '0');
450+
vis.array.select(2, cur_R, 2, cur_R, '0');
370451
}
452+
// colour all of M list, up to + including cur_E
453+
// (we don't color up to Null because the tail of E hasn't
454+
// been smashed)
455+
let Tails = Lists[2];
456+
for (let i = cur_M; i !== cur_E; i = Tails[i]) {
457+
vis.array.select(1, i, 1, i, '1');
458+
vis.array.select(2, i, 2, i, '1');
459+
}
460+
if (cur_E !== 'Null') {
461+
vis.array.select(1, cur_E, 1, cur_E, '1');
462+
vis.array.select(2, cur_E, 2, cur_E, '1');
463+
}
464+
}, [[Indices, Heads, Tails], L, R, M, E, simple_stack], depth);
465+
if (Heads[L] <= Heads[R]) {
466+
Tails[E] = L;
467+
E = L;
468+
L = Tails[L];
469+
chunker.add('popL', (vis, Lists, cur_L, cur_R, cur_M, cur_E, c_stk) => {
470+
vis.array.set(Lists, 'msort_lista_td');
471+
set_simple_stack(vis.array, c_stk);
472+
assignMaybeNullVar(vis, 'L', cur_L);
473+
assignMaybeNullVar(vis, 'R', cur_R);
474+
vis.array.assignVariable('M', 2, cur_M);
475+
assignMaybeNullVar(vis, 'E', cur_E);
476+
if (cur_L !== 'Null') {
477+
vis.array.select(1, cur_L, 1, cur_L, '0');
478+
vis.array.select(2, cur_L, 2, cur_L, '0');
479+
}
480+
if (cur_R !== 'Null') {
481+
vis.array.select(1, cur_R, 1, cur_R, '0');
482+
vis.array.select(2, cur_R, 2, cur_R, '0');
483+
}
484+
// colour all of M list, up to + including cur_E
485+
// (we don't color up to Null because the tail of E hasn't
486+
// been smashed)
487+
let Tails = Lists[2];
488+
for (let i = cur_M; i !== cur_E; i = Tails[i]) {
489+
vis.array.select(1, i, 1, i, '1');
490+
vis.array.select(2, i, 2, i, '1');
491+
}
492+
if (cur_E !== 'Null') {
493+
vis.array.select(1, cur_E, 1, cur_E, '1');
494+
vis.array.select(2, cur_E, 2, cur_E, '1');
495+
}
496+
}, [[Indices, Heads, Tails], L, R, M, E, simple_stack], depth);
497+
} else {
498+
Tails[E] = R;
499+
E = R;
500+
R = Tails[R];
501+
chunker.add('popR', (vis, Lists, cur_L, cur_R, cur_M, cur_E, c_stk) => {
502+
vis.array.set(Lists, 'msort_lista_td');
503+
set_simple_stack(vis.array, c_stk);
504+
assignMaybeNullVar(vis, 'L', cur_L);
505+
assignMaybeNullVar(vis, 'R', cur_R);
506+
vis.array.assignVariable('M', 2, cur_M);
507+
assignMaybeNullVar(vis, 'E', cur_E);
508+
if (cur_L !== 'Null') {
509+
vis.array.select(1, cur_L, 1, cur_L, '0');
510+
vis.array.select(2, cur_L, 2, cur_L, '0');
511+
}
512+
if (cur_R !== 'Null') {
513+
vis.array.select(1, cur_R, 1, cur_R, '0');
514+
vis.array.select(2, cur_R, 2, cur_R, '0');
515+
}
516+
// colour all of M list, up to + including cur_E
517+
// (we don't color up to Null because the tail of E hasn't
518+
// been smashed)
519+
let Tails = Lists[2];
520+
for (let i = cur_M; i !== cur_E; i = Tails[i]) {
521+
vis.array.select(1, i, 1, i, '1');
522+
vis.array.select(2, i, 2, i, '1');
523+
}
524+
if (cur_E !== 'Null') {
525+
vis.array.select(1, cur_E, 1, cur_E, '1');
526+
vis.array.select(2, cur_E, 2, cur_E, '1');
527+
}
528+
}, [[Indices, Heads, Tails], L, R, M, E, simple_stack], depth);
529+
}
371530
}
372531
// add any elements not scanned to the end of M
373-
if (L === 'Null')
374-
Tails[E] = R;
375-
else
376-
Tails[E] = L;
532+
if (L === 'Null') {
533+
Tails[E] = R;
534+
chunker.add('appendR', (vis, Lists, cur_L, cur_R, cur_M, cur_E, c_stk) => {
535+
vis.array.set(Lists, 'msort_lista_td');
536+
set_simple_stack(vis.array, c_stk);
537+
vis.array.assignVariable('M', 2, cur_M);
538+
// colour all of M list
539+
let Tails = Lists[2];
540+
for (let i = cur_M; i !== 'Null'; i = Tails[i]) {
541+
vis.array.select(1, i, 1, i, '1');
542+
vis.array.select(2, i, 2, i, '1');
543+
}
544+
}, [[Indices, Heads, Tails], L, R, M, E, simple_stack], depth);
545+
} else {
546+
Tails[E] = L;
547+
chunker.add('appendL', (vis, Lists, cur_L, cur_R, cur_M, cur_E, c_stk) => {
548+
vis.array.set(Lists, 'msort_lista_td');
549+
set_simple_stack(vis.array, c_stk);
550+
vis.array.assignVariable('M', 2, cur_M);
551+
// colour all of M list
552+
let Tails = Lists[2];
553+
for (let i = cur_M; i !== 'Null'; i = Tails[i]) {
554+
vis.array.select(1, i, 1, i, '1');
555+
vis.array.select(2, i, 2, i, '1');
556+
}
557+
}, [[Indices, Heads, Tails], L, R, M, E, simple_stack], depth);
558+
}
377559
chunker.add('returnM', (vis, Lists, cur_L, cur_M, c_stk) => {
378560
vis.array.set(Lists, 'msort_lista_td');
379561
set_simple_stack(vis.array, c_stk);
380562
vis.array.assignVariable('L', 2, undefined);
381563
vis.array.assignVariable('R', 2, undefined);
564+
vis.array.assignVariable('E', 2, undefined);
382565
vis.array.assignVariable('M', 2, cur_M);
566+
// colour all of M list
567+
let Tails = Lists[2];
568+
for (let i = cur_M; i !== 'Null'; i = Tails[i]) {
569+
vis.array.select(1, i, 1, i, '1');
570+
vis.array.select(2, i, 2, i, '1');
571+
}
383572
}, [[Indices, Heads, Tails], L, M, simple_stack], depth);
384573

385574

@@ -597,6 +786,8 @@ cur_right, c_stk) => {
597786
else
598787
{
599788
chunker.add('returnL', (vis, a, cur_L) => {
789+
vis.array.select(1, cur_L, 1, cur_L, '1');
790+
vis.array.select(2, cur_L, 2, cur_L, '1');
600791
// if (cur_left === cur_right) {
601792
// unhighlight(vis, cur_left, true);
602793
// highlight(vis, cur_left, false)

0 commit comments

Comments
 (0)