' The following Quicksort functions were written for Microsoft
' BASIC and Microsoft 'C', and should be portable from DOS to
' Windows (Visual) compilers, as well as other platforms.
'
' Each function contains the same number of lines, and in fact
' is quite similar, illustrating some of the similarities and
' differences in the two languages.

' The following 3 lines are specific to BASIC for DOS;
' use individual DIM statements in Visual Basic code.

defstr c
defint i
deflng l

function ifn.sort(int1(), int2(), istk(), imax) '/* array Quicksort function */
   iex1 = 0                          '/* initialize the outer-loop exit flag */
   iex2 = 0                          '/* initialize the inner-loop exit flag */
   ilap = 0                             '/* initialize the low array pointer */
   ilsp = 0                             '/* initialize the low stack pointer */
   irdx = 0                                    '/* initialize the sort radix */
   itap = 0                             '/* initialize the top array pointer */
   itsp = 0                             '/* initialize the top stack pointer */
   iva1 = 0                '/* initialize array value from low stack pointer */
   iva2 = 0                '/* initialize array value from low stack pointer */

   istk(0) = 0                          '/* initialize the low array pointer */
   istk(1) = imax                       '/* initialize the top array pointer */
   while irdx >= 0                             '/* loop until sort radix < 0 */
      ilsp = istk(irdx + irdx)                 '/* set the low stack pointer */
      itsp = istk(irdx + irdx + 1)             '/* set the top stack pointer */
      irdx = irdx - 1                           '/* decrement the sort radix */
      iva1 = int1(ilsp)           '/* get array value from low stack pointer */
      iva2 = int2(ilsp)           '/* get array value from low stack pointer */
      ilap = ilsp                              '/* set the low array pointer */
      itap = itsp + 1                          '/* set the top array pointer */
      iex1 = 0                       '/* initialize the outer-loop exit flag */
      while not iex1                 '/* loop to sort within the radix limit */
         itap = itap - 1                 '/* decrement the top array pointer */
         if itap = ilap then        '/* top array pointer==low array pointer */
            iex1 = not 0                 '/* set the outer-loop exit flag ON */
         elseif iva2 > int2(itap) then   '/* value @low ptr > value @top ptr */
            int1(ilap) = int1(itap)        '/* swap low and top array values */
            int2(ilap) = int2(itap)        '/* swap low and top array values */
            iex2 = 0                 '/* initialize the inner-loop exit flag */
            while not iex2         '/* loop to compare and swap array values */
               ilap = ilap + 1           '/* increment the low array pointer */
               if itap = ilap then  '/* top array pointer==low array pointer */
                  iex1 = not 0           '/* set the outer-loop exit flag ON */
                  iex2 = not 0           '/* set the inner-loop exit flag ON */
               elseif iva2 < int2(ilap) then '/* value@low ptr<value@low ptr */
                  int1(itap) = int1(ilap)  '/* swap top and low array values */
                  int2(itap) = int2(ilap)  '/* swap top and low array values */
                  iex2 = not 0           '/* set the inner-loop exit flag ON */
               end if
            wend
         end if
      wend
      int1(ilap) = iva1           '/* put array value from low stack pointer */
      int2(ilap) = iva2           '/* put array value from low stack pointer */
      if itsp - ilap > 1 then                   '/* low segment-width is > 1 */
         irdx = irdx + 1                        '/* increment the sort radix */
         istk(irdx + irdx) = ilap + 1            '/* reset low array pointer */
         istk(irdx + irdx + 1) = itsp            '/* reset top array pointer */
      end if
      if itap - ilsp > 1 then                   '/* top segment-width is > 1 */
         irdx = irdx + 1                        '/* increment the sort radix */
         istk(irdx + irdx) = ilsp                '/* reset low array pointer */
         istk(irdx + irdx + 1) = itap - 1        '/* reset top array pointer */
      end if
   wend
end function

' -----------------------------------------------------------------------------
' The following 2 lines are used to specify the
' shortcut declarations for the below function.

typedef int  I;                                    /* short integer (signed) */
typedef void V;                                            /* void data type */

V ifn_sort(I *int1, I *int2, I *istk, I imax) {  /* array Quicksort function */
   I iex1;                            /* initialize the outer-loop exit flag */
   I iex2;                            /* initialize the inner-loop exit flag */
   I ilap;                               /* initialize the low array pointer */
   I ilsp;                               /* initialize the low stack pointer */
   I irdx = 0;                                  /* initialize the sort radix */
   I itap;                               /* initialize the top array pointer */
   I itsp;                               /* initialize the top stack pointer */
   I iva1;                  /* initialize array value from low stack pointer */
   I iva2;                  /* initialize array value from low stack pointer */

   istk[0] = 0;                          /* initialize the low array pointer */
   istk[1] = imax;                       /* initialize the top array pointer */
   while (irdx >= 0) {                          /* loop until sort radix < 0 */
      ilsp = istk[irdx + irdx];                 /* set the low stack pointer */
      itsp = istk[irdx + irdx + 1];             /* set the top stack pointer */
      irdx--;                                    /* decrement the sort radix */
      iva1 = int1[ilsp];           /* get array value from low stack pointer */
      iva2 = int2[ilsp];           /* get array value from low stack pointer */
      ilap = ilsp;                              /* set the low array pointer */
      itap = itsp + 1;                          /* set the top array pointer */
      iex1 = 0;                       /* initialize the outer-loop exit flag */
      while (!iex1) {                 /* loop to sort within the radix limit */
         itap--;                          /* decrement the top array pointer */
         if (itap == ilap) {         /* top array pointer==low array pointer */
            iex1 = 1;                     /* set the outer-loop exit flag ON */
         } else if (iva2 > int2[itap]) {  /* value @low ptr > value @top ptr */
            int1[ilap] = int1[itap];        /* swap low and top array values */
            int2[ilap] = int2[itap];        /* swap low and top array values */
            iex2 = 0;                 /* initialize the inner-loop exit flag */
            while (!iex2) {         /* loop to compare and swap array values */
               ilap++;                    /* increment the low array pointer */
               if (itap == ilap) {   /* top array pointer==low array pointer */
                  iex1 = 1;               /* set the outer-loop exit flag ON */
                  iex2 = 1;               /* set the inner-loop exit flag ON */
               } else if (iva2 < int2[ilap]) {/* value@low ptr<value@low ptr */
                  int1[itap] = int1[ilap];  /* swap top and low array values */
                  int2[itap] = int2[ilap];  /* swap top and low array values */
                  iex2 = 1;               /* set the inner-loop exit flag ON */
               }
            }
         }
      }
      int1[ilap] = iva1;           /* put array value from low stack pointer */
      int2[ilap] = iva2;           /* put array value from low stack pointer */
      if (itsp - ilap > 1) {                     /* low segment-width is > 1 */
         irdx++;                                 /* increment the sort radix */
         istk[irdx + irdx] = ilap + 1;            /* reset low array pointer */
         istk[irdx + irdx + 1] = itsp;            /* reset top array pointer */
      }
      if (itap - ilsp > 1) {                     /* top segment-width is > 1 */
         irdx++;                                 /* increment the sort radix */
         istk[irdx + irdx] = ilsp;                /* reset low array pointer */
         istk[irdx + irdx + 1] = itap - 1;        /* reset top array pointer */
      }
   }
}
