psmile_quicksort.F90

Go to the documentation of this file.
00001 !-----------------------------------------------------------------------
00002 ! Copyright 2006-2010, NEC Europe Ltd., London, UK.
00003 ! All rights reserved. Use is subject to OASIS4 license terms.
00004 !-----------------------------------------------------------------------
00005 !BOP
00006 !
00007 ! !ROUTINE: PSMILe_Quicksort
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_quicksort(a, n)
00012 !
00013 ! !USES:
00014 !
00015         use PSMILe, dummy_interface => PSMILe_Quicksort
00016 
00017         implicit none
00018 !
00019 ! !INPUT PARAMETERS:
00020 !
00021         integer, intent(In)    :: n
00022 !
00023 ! !INPUT/OUTPUT PARAMETERS:
00024 !
00025         integer, intent(InOut) :: a(n)
00026 !
00027 ! !LOCAL VARIABLES
00028 !
00029         integer, Parameter     :: pointer_inc = 64
00030         integer                :: pointer_size
00031         integer, pointer       :: stackl(:), stackr(:)
00032         integer, pointer       :: new_stackl(:), new_stackr(:)
00033 
00034         integer                :: i, j, k, l, r, s
00035         integer                :: w, x
00036 !
00037 ! !DESCRIPTION:
00038 !
00039 ! Non-recursive stack version of Quicksort from N. Wirth's Pascal Book,
00040 ! 'Algorithms + Data Structures = Programms'.
00041 !
00042 ! taken from:
00043 !    http://www.nag.com/nagware/examples.asp
00044 !    http://www.nag.com/nagware/Examples/nur.f90
00045 !
00046 ! see also:
00047 !    http://en.wikipedia.org/wiki/Quicksort
00048 !
00049 ! !REVISION HISTORY:
00050 !
00051 !   Date      Programmer   Description
00052 ! ----------  ----------   -----------
00053 ! 19.07.95    Alan Miller  created
00054 ! 13.02.08    R. Redler    revised
00055 !
00056 !----------------------------------------------------------------------
00057 !
00058 !  Initialization
00059 !
00060 #ifdef VERBOSE
00061         print 9990, trim(ch_id)
00062 
00063         call psmile_flushstd
00064 #endif /* VERBOSE */
00065 
00066         pointer_size = pointer_inc
00067 
00068         allocate(new_stackl(pointer_inc), new_stackr(pointer_inc))
00069 
00070         stackl => new_stackl
00071         stackr => new_stackr
00072 
00073         s = 1
00074         stackl(1) = 1
00075         stackr(1) = n
00076         !
00077         !  Start sorting
00078         !        
00079         ! ... keep taking the top request from the stack until s = 0.
00080 
00081 10      continue
00082         l = stackl(s)
00083         r = stackr(s)
00084         s = s - 1
00085 
00086         ! ... keep splitting a(l), ... ,a(r) until l>= r.
00087 
00088 20      continue
00089         i = l
00090         j = r
00091         k = (l+r) / 2
00092         x = a(k)
00093 
00094         ! ... repeat until i > j.
00095 
00096         do
00097            do
00098               if (a(i) < x) then ! Search from lower end
00099                  i = i + 1
00100                  cycle
00101               else
00102                  exit
00103               end if
00104            end do
00105 
00106            do
00107               if (x < a(j)) then ! Search from upper end
00108                  j = j - 1
00109                  cycle
00110               else
00111                  exit
00112               end if
00113            end do
00114 
00115            if (i <= j) then ! Swap positions i & j
00116               w = a(i)
00117               a(i) = a(j)
00118               a(j) = w
00119               i = i + 1
00120               j = j - 1
00121               if (i.gt.j) exit
00122            else
00123               exit
00124            end if
00125         end do
00126 
00127         if (j-l >= r-i) then
00128 
00129            if (l < j) then
00130 
00131               if ( s+1 > pointer_size ) then
00132                  pointer_size = pointer_size + pointer_inc
00133                  allocate(new_stackl(pointer_size), new_stackr(pointer_size))
00134                  new_stackl(1:pointer_size-pointer_inc) = &
00135                      stackl(1:pointer_size-pointer_inc)
00136                  new_stackr(1:pointer_size-pointer_inc) = &
00137                      stackr(1:pointer_size-pointer_inc)
00138                  deallocate(stackl, stackr)
00139                  stackl => new_stackl
00140                  stackr => new_stackr
00141               endif
00142 
00143               s = s + 1
00144               stackl(s) = l
00145               stackr(s) = j
00146            end if
00147            l = i
00148 
00149         else
00150 
00151            if (i < r) then
00152 
00153               if ( s+1 > pointer_size ) then
00154                  pointer_size = pointer_size + pointer_inc
00155                  allocate(new_stackl(pointer_size), new_stackr(pointer_size))
00156                  new_stackl(1:pointer_size-pointer_inc) = &
00157                      stackl(1:pointer_size-pointer_inc)
00158                  new_stackr(1:pointer_size-pointer_inc) = &
00159                      stackr(1:pointer_size-pointer_inc)
00160                  deallocate(stackl, stackr)
00161                  stackl => new_stackl
00162                  stackr => new_stackr
00163               endif
00164 
00165               s = s + 1
00166               stackl(s) = i
00167               stackr(s) = r
00168            end if
00169            r = j
00170 
00171         end if
00172 
00173         if (l <  r) GO TO 20
00174         if (s /= 0) GO TO 10
00175 
00176 #ifdef VERBOSE
00177         print 9980, trim(ch_id), pointer_size
00178 
00179         call psmile_flushstd
00180 #endif /* VERBOSE */
00181         !
00182         !  Formats:
00183         !
00184 9990    format (1x, a, ': psmile_quicksort')
00185 9980    format (1x, a, ': psmile_quicksort: eof, stack size was ', i8)
00186 
00187       end subroutine PSMILe_Quicksort

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1