Return integer array p which indexes array a in increasing order. Array a is not disturbed. The Quicksort algorithm is used.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer, | intent(in) | :: | n | |||
real(kind=wp), | intent(in), | dimension(n) | :: | a | ||
integer, | intent(out), | dimension(n) | :: | p |
subroutine rqsort(n,a,p) implicit none integer,intent(in) :: n real(wp),dimension(n),intent(in) :: a integer,dimension(n),intent(out) :: p !Constants integer,parameter :: LGN = 32 !! log base 2 of maximum n integer,parameter :: Q = 11 !! smallest subfile to use quicksort on !Local: integer,dimension(LGN) :: stackl,stackr real(wp) :: x integer :: s,t,l,m,r,i,j !Initialize the stack stackl(1) = 1 stackr(1) = n l = stackl(1) r = stackr(1) s = 1 !Initialize the pointer array p = [(i, i=1,n)] do while (s>0) s = s - 1 if ((r-l)<Q) then !Use straight insertion insertion: do i=l+1,r t = p(i) x = a(t) do j=i-1,l,-1 if (a(p(j))<=x) then p(j+1) = t cycle insertion end if p(j+1) = p(j) end do j=l-1 p(j+1) = t end do insertion else !Use quicksort, with pivot as median of a(l), a(m), a(r) m=(l+r)/2 t=p(m) if (a(t)<a(p(l))) then p(m)=p(l) p(l)=t t=p(m) end if if (a(t)>a(p(r))) then p(m)=p(r) p(r)=t t=p(m) if (a(t)<a(p(l))) then p(m)=p(l) p(l)=t t=p(m) end if end if !Partition x=a(t) i=l+1 j=r-1 do while (i<=j) do while (a(p(i))<x) i=i+1 end do do while (x<a(p(j))) j=j-1 end do if (i<=j) then t=p(i) p(i)=p(j) p(j)=t i=i+1 j=j-1 end if end do !Stack the larger subfile s=s+1 if ((j-l)>(r-i)) then stackl(s)=l stackr(s)=j l=i else stackl(s)=i stackr(s)=r r=j end if s = s + 1 ! since it will be decremented next cycle cycle end if if (s>0) then l = stackl(s) r = stackr(s) end if end do end subroutine rqsort