77// #define QUICKSORT // some version of quicksort
88// #define MERGE_TD // top-down merge sort
99// #define MERGE_BUP // bottom-up merge sort
10+ #define MERGE_NAT // natural merge sort
1011// #define MSD_RADIX // radix exchange sort
11- #define MERGE_TD_LA // top-down merge sort for lists imp as arrays
12+ // #define MERGE_TD_LA // top-down merge sort for lists imp as arrays
1213// XXX should do top-down merge sort for lists imp with pointers - main code
1314// should be identical - just need to write init code for list and change
1415// some macro definitions
@@ -59,6 +60,10 @@ List mergesort_td_la(int L, int len);
5960void mergesort_bup (int A [], int size );
6061#endif // MERGE_BUP
6162
63+ #ifdef MERGE_NAT
64+ void mergesort_nat (int A [], int size );
65+ #endif // MERGE_NAT
66+
6267#ifdef MSD_RADIX
6368int radix_partition (int * A , int left , int right , int mask );
6469void msd_radix_sort (int A [], int left , int right , int mask );
@@ -102,6 +107,9 @@ main() {
102107#ifdef MERGE_BUP
103108 mergesort_bup (A , Size - 1 );
104109#endif // MERGE_BUP
110+ #ifdef MERGE_NAT
111+ mergesort_nat (A , Size - 1 );
112+ #endif // MERGE_NAT
105113 for (i = 1 ; i < Size ; i ++ ) printf ("%d " , A [i ]); printf ("\n" );
106114}
107115
@@ -323,7 +331,7 @@ mergesort_td(int A[], int left, int right) {
323331List
324332mergesort_td_la (int L , int len ) {
325333 int i , mid ;
326- List Lmid , R , M , E ;
334+ List Lmid , R , M , Mlast ;
327335
328336 if (len > 1 ) {
329337 // determine Lmid, the mid point of L
@@ -362,23 +370,23 @@ mergesort_td_la(int L, int len) {
362370 R = tail (R );
363371 }
364372 // scan through adding elements to the end of M
365- E = M ;
373+ Mlast = M ;
366374 while (L != Null && R != Null ) {
367375 if (head (L ) <= head (R )) {
368- tail (E ) = L ;
369- E = L ;
376+ tail (Mlast ) = L ;
377+ Mlast = L ;
370378 L = tail (L );
371379 } else {
372- tail (E ) = R ;
373- E = R ;
380+ tail (Mlast ) = R ;
381+ Mlast = R ;
374382 R = tail (R );
375383 }
376384 }
377385 // add any elements not scanned to the end of M
378386 if (L == Null )
379- tail (E ) = R ;
387+ tail (Mlast ) = R ;
380388 else
381- tail (E ) = L ;
389+ tail (Mlast ) = L ;
382390 printf ("Merged: " );
383391 for (Lmid = M ; Lmid != Null ; Lmid = tail (Lmid ))
384392 printf (" %d" , head (Lmid ));
@@ -397,7 +405,7 @@ mergesort_td_la(int L, int len) {
397405#endif // MERGE_TD_LA
398406
399407#ifdef MERGE_BUP
400- // XXX could reduce duplication with MERGE_TD
408+ // XXX could reduce duplication with MERGE_TD and MERGE_NAT
401409int B [Size ];
402410
403411int
@@ -460,3 +468,77 @@ printf("Merging %d %d %d - %d\n", left, mid, right, runlength);
460468}
461469
462470#endif // MERGE_BUP
471+
472+ #ifdef MERGE_NAT
473+ // XXX could reduce duplication with MERGE_TD and MERGE_BUP
474+ int B [Size ];
475+
476+ int
477+ minimum (int i , int j ) {
478+ if (i <= j )
479+ return i ;
480+ else
481+ return j ;
482+ }
483+
484+ // Sort array A[1]..A[size] in ascending order
485+ void
486+ mergesort_nat (int A [], int size ) {
487+ int runcount , left , mid , right ;
488+ int ap1 , ap1max , ap2 , ap2max , bp ;
489+
490+ do {
491+ runcount = 0 ;
492+ left = 1 ;
493+ do {
494+ // find the first run, A[left..mid]
495+ mid = left ;
496+ while (mid < size && A [mid ] <= A [mid + 1 ])
497+ mid ++ ;
498+ // find the second run, A[mid+1..right]
499+ right = mid + 1 ;
500+ while (right < size && A [right ] <= A [right + 1 ])
501+ right ++ ;
502+ if (mid < size ) {
503+ // merge A[left..mid] and A[mid+1..right], with the result in A
504+ printf ("Merging %d %d %d \n" , left , mid , right );
505+ ap1 = left ;
506+ ap1max = mid ;
507+ ap2 = mid + 1 ;
508+ ap2max = right ;
509+ bp = left ;
510+ while (ap1 <= ap1max && ap2 <= ap2max )
511+ if (A [ap1 ] < A [ap2 ]) {
512+ B [bp ] = A [ap1 ];
513+ ap1 = ap1 + 1 ;
514+ bp = bp + 1 ;
515+ } else {
516+ B [bp ] = A [ap2 ];
517+ ap2 = ap2 + 1 ;
518+ bp = bp + 1 ;
519+ }
520+ while (ap1 <= ap1max ) {
521+ B [bp ] = A [ap1 ];
522+ ap1 = ap1 + 1 ;
523+ bp = bp + 1 ;
524+ }
525+ while (ap2 <= ap2max ) {
526+ B [bp ] = A [ap2 ];
527+ ap2 = ap2 + 1 ;
528+ bp = bp + 1 ;
529+ }
530+ for (bp = left ; bp <= right ; bp ++ )
531+ A [bp ] = B [bp ];
532+ }
533+ runcount ++ ;
534+ left = right + 1 ;
535+ } while (left < size );
536+ } while (runcount > 1 );
537+ // if (left < right-1) { // for testing/debugging
538+ // int i1;
539+ // printf("Ret from ms(%d, %d): ", left, right);
540+ // for (i1=1; i1 < Size; i1++) printf("%d ", A[i1]); printf("\n");
541+ // }
542+ }
543+
544+ #endif // MERGE_NAT
0 commit comments