1+ // src/algorithms/sorting/mergeSort.js
2+ export function * mergeSort ( array ) {
3+ const arr = [ ...array ] ;
4+ const n = arr . length ;
5+
6+ if ( n === 0 ) {
7+ yield { type : "done" , array : arr } ;
8+ return ;
9+ }
10+
11+ function * merge ( l , m , r ) {
12+ const left = arr . slice ( l , m + 1 ) ;
13+ const right = arr . slice ( m + 1 , r + 1 ) ;
14+ let i = 0 ;
15+ let j = 0 ;
16+ let k = l ;
17+
18+ while ( i < left . length && j < right . length ) {
19+ // highlight the two elements being compared (use their original indices)
20+ yield { type : "compare" , indices : [ l + i , m + 1 + j ] } ;
21+
22+ if ( left [ i ] <= right [ j ] ) {
23+ arr [ k ] = left [ i ] ;
24+ yield { type : "swap" , indices : [ k , l + i ] , array : [ ...arr ] } ;
25+ i ++ ;
26+ } else {
27+ arr [ k ] = right [ j ] ;
28+ yield { type : "swap" , indices : [ k , m + 1 + j ] , array : [ ...arr ] } ;
29+ j ++ ;
30+ }
31+ k ++ ;
32+ }
33+
34+ while ( i < left . length ) {
35+ arr [ k ] = left [ i ] ;
36+ yield { type : "swap" , indices : [ k , l + i ] , array : [ ...arr ] } ;
37+ i ++ ;
38+ k ++ ;
39+ }
40+
41+ while ( j < right . length ) {
42+ arr [ k ] = right [ j ] ;
43+ yield { type : "swap" , indices : [ k , m + 1 + j ] , array : [ ...arr ] } ;
44+ j ++ ;
45+ k ++ ;
46+ }
47+
48+ // mark merged positions as "min" to indicate they're in final place for this merge
49+ for ( let idx = l ; idx <= r ; idx ++ ) {
50+ yield { type : "min" , index : idx } ;
51+ }
52+ }
53+
54+ function * mergeSortRec ( l , r ) {
55+ if ( l >= r ) return ;
56+ const m = Math . floor ( ( l + r ) / 2 ) ;
57+ yield * mergeSortRec ( l , m ) ;
58+ yield * mergeSortRec ( m + 1 , r ) ;
59+ yield * merge ( l , m , r ) ;
60+ }
61+
62+ yield * mergeSortRec ( 0 , n - 1 ) ;
63+ yield { type : "done" , array : arr } ;
64+ }
0 commit comments