C# proc: xkthp2 - rearranges data within a 2D array finding the kth largest of
C# proc:          n elements without sorting.

C Find the |k|${}^{th}$-largest of |N| elements without sorting.
C Algorithm is procedure |find| from p. 84 of Wirth,
C {\em Algorithms + Data Structures = Programs}. In average case,
C takes about $O(N)$ work; worst case takes $O(N^2)$ work.

C Re-arranges data in |x| array from |x(n,first)| to |x(n,last)|.
C Ends up with |x(n,kth)| the |k|${}^{th}$-largest in this range.
C |x(n,i) <= x(n,kth)| for |first <= i < kth|, and
C |x(n,kth) <= x(n,j)| for |kth < j <= last|.
      

C FTANGLE v1.22, tangled with SunOS/UNIX on "Saturday, September 21, 1991 at 12:
C 39." 
C COMMAND LINE: "ftangle -mSUN -v -# xkthp2.web"
C RUN TIME: "Wednesday, May 11, 1994 at 11:24."
C WEB FILE:    "xkthp2.web"
C CHANGE FILE: ""
      real function xkthp2(k,x,ndim,nmax,n,m,first,last)
        
        real x(nmax,ndim)
        integer m(*)
        integer first
        
        integer left,right,i,j
        real value,temp
        
C/print *, "xkthp2: finding number ", k, " in range ", first, last; 
        left=first
        right=last
        kth=first+k-1
        
        CONTINUE
C ---  "while(left<right)" ---
90000   IF(left.LT.right)THEN
          value=x(n,kth)
          i=left
          j=right
          CONTINUE
C ---  "repeat" ---
90002     CONTINUE
            CONTINUE
C ---  "while(x(n,i)<value)" ---
90005       IF(x(n,i).LT.value)THEN
              i=i+1
              GOTO 90005
            ENDIF
            CONTINUE
C ---  "while(value<x(n,j))" ---
90007       IF(value.LT.x(n,j))THEN
              j=j-1
              GOTO 90007
            ENDIF
            CONTINUE
C ---  "if" ---
            IF(i.LE.j)THEN
              CONTINUE
C ---  "do" ---
              DO 90009 nn=1,nmax
                temp=x(nn,i)
                x(nn,i)=x(nn,j)
                x(nn,j)=temp
90009         CONTINUE
              itmp=m(i)
              m(i)=m(j)
              m(j)=itmp
              i=i+1
              j=j-1
            ENDIF
C ---  "until(i>j)" ---
          IF(.NOT.(i.GT.j))GOTO 90002
          
          CONTINUE
C ---  "if" ---
          IF(j.LT.kth)THEN
            left=i
          ENDIF
          CONTINUE
C ---  "if" ---
          IF(kth.LT.i)THEN
            right=j
          ENDIF
          GOTO 90000
        ENDIF
C/print *, "kth is ", kth, x(n,kth); 
        CONTINUE
C ---  "return x(n,kth)" ---
        xkthp2=x(n,kth)
        RETURN
      END
      
      
