      SUBROUTINE ISORTQ(A,IDX,N)    ! quick sort (integer)
*     integer keys A(*), unchanged at return 
*     N indices IDX(1) ... IDX(N), changed at return such that
*        A(IDX(L)) <= A(IDX(L+1)) 
      INTEGER NLEV          ! stack size
      PARAMETER (NLEV=2*32) ! ... for N = 2**32 = 4.3 10**9
      INTEGER I,J,L,R,IDXT,N,IDX(N),LEV,LR(NLEV)
      INTEGER A(*),AT       ! array of keys and pivot key
      LEV=0
      L=1
      R=N
 10   IF(R-L.EQ.1) THEN     ! sort two elements
         IF(A(IDX(L)).GT.A(IDX(R))) THEN
            IDXT   = IDX(L) ! exchange
            IDX(L) = IDX(R)
            IDX(R) = IDXT  
         END IF 
         R=L 
      END IF
      IF(R.EQ.L) THEN  
         IF(LEV.LE.0) RETURN   
         LEV=LEV-2 
         L=LR(LEV+1)
         R=LR(LEV+2)
      ELSE
         AT=A(IDX((L+R)/2))
         I=L-1       ! find limits [J,I] with [L,R]
         J=R+1
 20      I=I+1
         IF(A(IDX(I)).LT.AT) GOTO 20 
 30      J=J-1
         IF(A(IDX(J)).GT.AT) GOTO 30 
         IF(I.LE.J) THEN
            IDXT   = IDX(I)
            IDX(I) = IDX(J)
            IDX(J) = IDXT
            GO TO 20
         END IF
         IF(LEV+2.GT.NLEV) STOP ' SORTQS: stack overflow '
         IF(R-I.LT.J-L) THEN 
            LR(LEV+1)=L
            LR(LEV+2)=J
            L=I
         ELSE 
            LR(LEV+1)=I
            LR(LEV+2)=R
            R=J
         END IF 
         LEV=LEV+2
      END IF
      GO TO 10
      END
