Skip to content

Commit 0463bfd

Browse files
committed
Quicksort stack, left, right
1 parent d2af02b commit 0463bfd

File tree

1 file changed

+81
-38
lines changed

1 file changed

+81
-38
lines changed

src/algorithms/controllers/quickSort_shared.js

Lines changed: 81 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ const VIS_VARIABLE_STRINGS = {
5656
i_eq_0: 'i=0',
5757
j_eq_0: 'j=0',
5858
pivot: 'pivot',
59+
left: 'left',
60+
right: 'right',
61+
right_lt_left: 'right<left'
5962
};
6063

6164
// see stackFrameColour in index.js to find corresponding function mapping to css
@@ -64,9 +67,18 @@ const STACK_FRAME_COLOR = {
6467
In_progress_stackFrame: 1,
6568
Current_stackFrame: 2,
6669
Finished_stackFrame: 3,
67-
I_color: 4,
68-
J_color: 5,
69-
P_color: 6, // pivot
70+
// I_color: 4,
71+
// J_color: 5,
72+
// P_color: 6, // pivot
73+
// Disabling stack coloring for i, j, pivot - a bit too busy, doesn't
74+
// really add much if anything and NQR at end of partition in some
75+
// cases(?) Just set colors to same as Current_stackFrame for now
76+
// - best clean up the code and refactor - want radix exchange
77+
// sort (currently horrible messy code), quicksort(s) and eventually
78+
// top-down merge sort for arrays to look very similar. XXX
79+
I_color: 2,
80+
J_color: 2,
81+
P_color: 2, // pivot
7082
};
7183

7284

@@ -203,7 +215,8 @@ export function run_QS(is_qs_median_of_3) {
203215
// Define helper functions
204216
// ----------------------------------------------------------------------------------------------------------------------------
205217

206-
function derive_stack(cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) {
218+
function derive_stack(cur_real_stack, cur_finished_stack_frames,
219+
cur_i, cur_j, cur_pivot_index, cur_left, cur_right, cur_depth) {
207220
// return 2D array stack_vis containing color values corresponding to stack frame states and indexes in those stack frames
208221
// for visualise this data
209222

@@ -264,9 +277,9 @@ export function run_QS(is_qs_median_of_3) {
264277
return stack_vis;
265278
}
266279

267-
const refresh_stack = (vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) => {
280+
// Note: refreshes stack and also indices on array
281+
const refresh_stack = (vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_left, cur_right, cur_depth) => {
268282

269-
// XXX
270283
// We can't render the -1 index in the array
271284
// For now we display i==0/j==0 at left of array if appropriate
272285
let cur_i_too_low;
@@ -283,6 +296,15 @@ export function run_QS(is_qs_median_of_3) {
283296
} else {
284297
cur_j_too_low = undefined;
285298
}
299+
// right can fall of the left of array, left can fall off right
300+
let cur_right_lt_left;
301+
if (cur_right === -1) {
302+
cur_right = undefined;
303+
cur_right_lt_left = 0;
304+
} else if (cur_left === entire_num_array.length) {
305+
cur_right_lt_left = cur_right;
306+
cur_left = undefined;
307+
}
286308

287309
assert(vis.array);
288310
assert(cur_real_stack && cur_finished_stack_frames);
@@ -299,16 +321,22 @@ export function run_QS(is_qs_median_of_3) {
299321
cur_i_too_low = undefined;
300322
}
301323

302-
vis.array.setStackDepth(cur_real_stack.length);
303-
vis.array.setStack(
304-
derive_stack(cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth)
305-
);
324+
if (isRecursionExpanded()) {
325+
vis.array.setStackDepth(cur_real_stack.length);
326+
vis.array.setStack(
327+
derive_stack(cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_left, cur_right, cur_depth)
328+
);
329+
} else
330+
vis.array.setStack([]);
306331

307332
assign_i_j(vis, VIS_VARIABLE_STRINGS.i_left_index, cur_i);
308333
assign_i_j(vis, VIS_VARIABLE_STRINGS.i_eq_0, cur_i_too_low);
309334
assign_i_j(vis, VIS_VARIABLE_STRINGS.pivot, cur_pivot_index);
310335
assign_i_j(vis, VIS_VARIABLE_STRINGS.j_right_index, cur_j);
311336
assign_i_j(vis, VIS_VARIABLE_STRINGS.j_eq_0, cur_j_too_low);
337+
assign_i_j(vis, VIS_VARIABLE_STRINGS.left, cur_left);
338+
assign_i_j(vis, VIS_VARIABLE_STRINGS.right, cur_right);
339+
assign_i_j(vis, VIS_VARIABLE_STRINGS.right_lt_left, cur_right_lt_left);
312340
};
313341

314342

@@ -363,15 +391,14 @@ export function run_QS(is_qs_median_of_3) {
363391
[a[n1], a[n2]] = [a[n2], a[n1]]
364392

365393
chunker.add(bookmark,
366-
(vis, _n1, _n2, cur_real_stack, cur_finished_stack_frames,
367-
cur_i, cur_j, cur_pivot_index, cur_depth, bm) => {
394+
(vis, _n1, _n2, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_left, cur_right, cur_depth, bm) => {
368395

369396
vis.array.swapElements(_n1, _n2);
370-
refresh_stack(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth);
397+
refresh_stack(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_left, cur_right, cur_depth);
371398
if (bm == QS_BOOKMARKS.SHARED_swap_pivot_into_position)
372399
vis.array.selectColor(_n1, sortedColor);
373400
},
374-
[n1, n2, real_stack, finished_stack_frames, i, j, pivot_index, depth, bookmark],
401+
[n1, n2, real_stack, finished_stack_frames, i, j, pivot_index, left, right, depth, bookmark],
375402
depth);
376403
}
377404

@@ -383,7 +410,8 @@ cur_i, cur_j, cur_pivot_index, cur_depth, bm) => {
383410
assert(bookmark !== undefined); // helps catch bugs early, and trace them in stack
384411

385412
if (args_array === undefined) {
386-
args_array = [real_stack, finished_stack_frames, i, j, pivot_index, depth]
413+
args_array = [real_stack, finished_stack_frames, i, j,
414+
pivot_index, left, right, depth]
387415
}
388416

389417
chunker.add(bookmark, f, args_array, depth)
@@ -423,7 +451,6 @@ cur_i, cur_j, cur_pivot_index, cur_depth, bm) => {
423451
vis.array.selectColor(fin_mid, pivotColor);
424452
vis.array.selectColor(fin_left, partLColor);
425453
vis.array.selectColor(fin_right, partRColor);
426-
// XXX check/fix above for small partitions
427454
},
428455
[finalmid, finalleft, finalright]);
429456

@@ -457,7 +484,7 @@ cur_i, cur_j, cur_pivot_index, cur_depth, bm) => {
457484
// if (cur_left !== cur_right -1)
458485
// unhighlight(vis, cur_left, false);
459486

460-
refresh_stack(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) // refresh stack to show pivot_index
487+
refresh_stack(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_left, cur_right, cur_depth) // refresh stack to show pivot_index
461488
},
462489
[right, left, real_stack, finished_stack_frames, i, j, pivot_index, depth]);
463490

@@ -468,7 +495,9 @@ cur_i, cur_j, cur_pivot_index, cur_depth, bm) => {
468495
chunker_add_if(
469496
QS_BOOKMARKS.RIGHT_P_set_pivot_to_value_at_array_indx_right,
470497
(vis, cur_right, cur_left, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) => {
471-
refresh_stack(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) // refresh stack to show pivot_index
498+
refresh_stack(vis, cur_real_stack,
499+
cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_left,
500+
cur_right, cur_depth) // refresh stack to show pivot_index
472501
vis.array.selectColor(cur_pivot_index, pivotColor);
473502
},
474503
[right, left, real_stack, finished_stack_frames, i, j, pivot_index, depth]);
@@ -516,8 +545,10 @@ cur_i, cur_j, cur_pivot_index, cur_depth, bm) => {
516545
iColor = partRColor;
517546
chunker_add_if(
518547
QS_BOOKMARKS.SHARED_incri_j_until,
519-
(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) => {
520-
refresh_stack(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth);
548+
(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_left, cur_right, cur_depth) => {
549+
refresh_stack(vis, cur_real_stack,
550+
cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_left,
551+
cur_right, cur_depth);
521552
vis.array.selectColor(cur_i, iColor);
522553
});
523554

@@ -533,9 +564,11 @@ cur_i, cur_j, cur_pivot_index, cur_depth, bm) => {
533564
jColor = partLColor;
534565
chunker_add_if(
535566
QS_BOOKMARKS.SHARED_decri_j_until,
536-
(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) => {
537-
refresh_stack(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth);
538-
if (cur_j >= left) // XXX pass in left?
567+
(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_left, cur_right, cur_depth) => {
568+
refresh_stack(vis, cur_real_stack,
569+
cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_left,
570+
cur_right, cur_depth);
571+
if (cur_j >= cur_left)
539572
vis.array.selectColor(cur_j, jColor);
540573
});
541574

@@ -555,14 +588,6 @@ cur_i, cur_j, cur_pivot_index, cur_depth, bm) => {
555588
swapAction(QS_BOOKMARKS.SHARED_swap_pivot_into_position, i,
556589
is_qs_median_of_3 ? right-1 : right
557590
);
558-
// XXX best make pivot sorted above and delete next chunk?
559-
/*
560-
chunker_add_if(
561-
QS_BOOKMARKS.SHARED_swap_pivot_into_position,
562-
(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) => {
563-
vis.array.sorted(cur_pivot_index);
564-
});
565-
*/
566591

567592
return [i, a]; // Return [pivot location, array partition_num_array]
568593
}
@@ -580,6 +605,11 @@ cur_i, cur_j, cur_pivot_index, cur_depth, bm) => {
580605
chunker.add(QS_BOOKMARKS.SHARED_if_left_less_right, refresh_stack, [
581606
real_stack,
582607
finished_stack_frames,
608+
undefined, // i
609+
undefined, // j
610+
undefined, // pivot
611+
left,
612+
right,
583613
], depth);
584614

585615
if (left < right) {
@@ -600,7 +630,8 @@ cur_i, cur_j, cur_pivot_index, cur_depth, bm) => {
600630
chunker.add(QS_BOOKMARKS.SHARED_pre_left,
601631
(vis, cur_right, cur_left, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth, old_pivot) => {
602632
refresh_stack(vis, cur_real_stack,
603-
cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) // refresh shows i
633+
cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_left,
634+
cur_right, cur_depth) // refresh shows i
604635
for (let i = cur_left; i <= cur_right; i++)
605636
if (i !== old_pivot)
606637
vis.array.deselect(i);
@@ -614,14 +645,16 @@ cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) // refresh
614645
// this level when the recursive code is collapsed
615646
chunker.add(QS_BOOKMARKS.SHARED_quicksort_left_to_i_minus_1,
616647
(vis, cur_right, cur_left, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) => {
617-
refresh_stack(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) // refresh shows i
648+
refresh_stack(vis, cur_real_stack, cur_finished_stack_frames,
649+
cur_i, cur_j, cur_pivot_index, cur_left, cur_right, cur_depth) // refresh shows i
618650
},
619651
[right, left, real_stack, finished_stack_frames, i, j, pivot_index, depth], depth);
620652

621653
// dummy chunk before recursive call, as above
622654
chunker.add(QS_BOOKMARKS.SHARED_pre_right,
623655
(vis, cur_right, cur_left, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) => {
624-
refresh_stack(vis, cur_real_stack, cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) // refresh shows i
656+
refresh_stack(vis, cur_real_stack, cur_finished_stack_frames,
657+
cur_i, cur_j, cur_pivot_index, cur_left, cur_right, cur_depth) // refresh shows i
625658
},
626659
[right, left, real_stack, finished_stack_frames, i, j, pivot_index, depth], depth);
627660

@@ -632,6 +665,11 @@ cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) // refresh
632665
chunker.add(QS_BOOKMARKS.SHARED_quicksort_i_plus_1_to_right, refresh_stack, [
633666
real_stack,
634667
finished_stack_frames,
668+
undefined, // i
669+
undefined, // j
670+
undefined, // pivot
671+
left,
672+
right,
635673
], depth);
636674
finished_stack_frames.push(real_stack.pop());
637675
}
@@ -668,11 +706,13 @@ cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) // refresh
668706

669707
chunker.add(
670708
QS_BOOKMARKS.SHARED_quicksort_left_to_right,
671-
(vis, array) => {
709+
(vis, array, cur_left, cur_right) => {
672710
vis.array.set(array, 'quicksort');
673711
vis.array.setStack([]); // used for a custom stack visualisation
712+
assign_i_j(vis, VIS_VARIABLE_STRINGS.left, cur_left);
713+
assign_i_j(vis, VIS_VARIABLE_STRINGS.right, cur_right);
674714
},
675-
[entire_num_array],
715+
[entire_num_array, 0, entire_num_array.length - 1],
676716
0);
677717

678718
const result = QuickSort(entire_num_array, 0, entire_num_array.length - 1, 1);
@@ -683,14 +723,17 @@ cur_finished_stack_frames, cur_i, cur_j, cur_pivot_index, cur_depth) // refresh
683723
chunker.add(
684724
QS_BOOKMARKS.SHARED_done_qs,
685725
(vis, idx) => {
686-
vis.array.setStackDepth(0);
687726
vis.array.fadeOut(idx);
688727
// fade all elements back in for final sorted state
689728
for (let i = 0; i < entire_num_array.length; i += 1) {
690729
vis.array.fadeIn(i);
691730
}
692731
vis.array.clearVariables();
693-
vis.array.setStack(derive_stack(real_stack, finished_stack_frames));
732+
if (isRecursionExpanded()) {
733+
vis.array.setStackDepth(0);
734+
vis.array.setStack(derive_stack(real_stack, finished_stack_frames));
735+
} else
736+
vis.array.setStack([]);
694737
},
695738
[entire_num_array.length - 1],
696739
0);

0 commit comments

Comments
 (0)