home *** CD-ROM | disk | FTP | other *** search
- PROGRAM SORTT
- # Test driver for quick address sort routine SORTI
- DIMENSION INDEX(64),IT(8),KAR(64)
- # Random data is best for finding bugs but RAND func not in F-80
- #DATA KAR/'AF','GH','FL','XH','EI','RT','AL','SL',
- #'RF','YN','SK','RM','SL','WM','QK','WM',
- #'FB','DK','FK','WB','EY','QX','ZX','SI',
- #'DL','TW','PI','RT','EF','VI','EJ','FY',
- #'SG','DG','WJ','RI','PR','EI','WJ','SO',
- #'AK','EG','YV','FD','VP','DI','XU','ZP',
- #'DF','LC','SV','DW','FW','ST','QF','FE',
- #'SH','LQ','WT','CY','VE','WK','XY','AN'/
- WRITE(3,5)
- 5 FORMAT(1X,'How many shall we sort?')
- READ(3,10)N
- 10 FORMAT(I2)
- DO I=1,N
- KAR(I)=(SIN(FLOAT(I))+1.)*16384.
- CALL SORTI(KAR,INDEX,N)
- WRITE(3,20)
- 20 FORMAT(1X,'Indexed test array')
- DO I=1,N,8
- $(DO J=1,8
- $(JI=I+J-1;IXJ=INDEX(JI);IT(J)=KAR(IXJ)$)
- WRITE(3,30)IT $)
- 30 FORMAT(8I6)
- STOP
- END
- SUBROUTINE SORTI(A,IX,N)
- define(MAXM,13)
- DIMENSION A(N),IX(N),I(MAXM),L(MAXM)
- # IX WILL BE INDEX TO THE N ELEMENTS OF A IN INCREASING ORDER
- # This type statement can be changed appropriately
- # or a comparison function can be used
- INTEGER A
- # INITIALIZE INDEX
- DO J=1,N
- IX(J)=J
- #ACTUAL MAXIMUM DIMENSION OF I,L IS LOG BASE 2 OF N
- M=1
- I(1)=1
- L(1)=N
- REPEAT $(
- IM=I(M)
- J=IM
- K=L(M)+1
- IF(K<J+2) M=M-1
- # IF SEGMENT M HAS 0 OR 1 MEMBER
- ELSE $(
- # NEARLY SORTED DATA PROCESS FASTER IF IX(J)&IX((K+J)/2)
- # ARE INTERCHANGED HERE FIRST
- # CHOOSE FIRST ELEMENT AS PIVOT
- IXIM=IX(J)
- # SEGMENT M HAS 2 OR MORE MEMBERS - PARTITION INTO 3 SEGMENTS
- # BEGIN LOOP 2 - FIND FIRST ENTRY TO BE MOVED TO END
- REPEAT $(J1=J+1;K1=K-1;DO J=J1,K1
- # This GOTO can be replaced by BREAK and the next BREAK omitted
- # however, this causes the next WHILE to execute unnecessarily
- $(IXJ=IX(J);IF(A(IXIM)<A(IXJ)) GOTO 120$)
- BREAK # IF HERE, DONE PARTIONING
- # FIND LAST ENTRY TO BE MOVED TO FRONT (LOOP 3)
- # NO NEED TO TEST K IN LOOP SINCE DATA WILL STOP LOOP
- 120 REPEAT $(K=K-1
- IXK=IX(K)$)UNTIL (A(IXIM)>=A(IXK))
- # SWAP IX(J) & IX(K)
- K=MAX0(K,J)
- IF(K==J)BREAK
- IT=IX(J)
- IX(J)=IX(K)
- IX(K)=IT
- $)# END OF REPEAT LOOP, EXITS AT 2 BREAKS
- # PUT FIRST ELEMENT BETWEEN 2 NEW SEGMENTS AT K-1
- IX(IM)=IX(K-1)
- IX(K-1)=IXIM
- # LARGER SEGMENT IS NEW SEGMENT M - SIZES ARE K-I(M)-1, L(M)-K+1
- IF(K*2-L(M)-IM<2)#IF TAIL SEGMENT LONGER
- $( I(M+1)=IM
- I(M)=K
- L(M+1)=K-2 $)
- ELSE $(I(M+1)=K
- L(M+1)=L(M)
- L(M)=K-2 $)
- # WORK ON SHORT SEGMENT NEXT
- M=M+1
- IF(M>MAXM)WRITE(3,90)
- 90 FORMAT(1X,'Number of segments in quicksort exceeds MAXM ')
- $) $) UNTIL (M<1 | M>MAXM)
- RETURN
- END
-