Re: adapting a quicksort



On Sat, 23 Aug 2008 19:51:44 -0600, Ron Ford posted:

I recently bumped into fortran.com as a resource and continue to be
impressed with its content. I found a quicksort for reals there and wanted
to adapt it:

http://www.fortran.com/qsort_c.f95

For starters, I want it to sort integers instead. Is that change as simple
as replacing 'real' with 'integer' in the following:

Apparently, it is:

! tja

module sort3
implicit none
private
public :: selection_sort
! type definition includes only an integer
type, public :: address
integer :: zip_code
end type address
contains
recursive subroutine selection_sort (array_arg)
type (address), dimension(:), intent (inout) &
:: array_arg
integer :: current_size
integer :: big
current_size = size (array_arg)
if (current_size > 0) then
big = maxloc(array_arg(:)%zip_code, dim=1)
call swap (big, current_size)
call selection_sort (array_arg(1: current_size -1))
end if
contains
subroutine swap(i,j)
integer, intent (in) :: i,j
type (address) :: temp
temp = array_arg(i)
array_arg(i) = array_arg(j)
array_arg(j) = temp
end subroutine swap
end subroutine selection_sort
end module sort3

! Recursive Fortran 95 quicksort routine
! sorts [integer] numbers into ascending numerical order
! Author: Juli Rew, SCD Consulting (juliana@xxxxxxxx), 9/03
! Based on algorithm from Cormen et al., Introduction to Algorithms,
! 1997 printing

! Made F conformant by Walt Brainerd

module qsort_c_module

implicit none
public :: QsortC
private :: Partition

contains

recursive subroutine QsortC(A)
integer, intent(in out), dimension(:) :: A
integer :: iq

if(size(A) > 1) then
call Partition(A, iq)
call QsortC(A(:iq-1))
call QsortC(A(iq:))
endif
end subroutine QsortC

subroutine Partition(A, marker)
integer, intent(in out), dimension(:) :: A
integer, intent(out) :: marker
integer :: i, j
integer :: temp
integer :: x ! pivot point
x = A(1)
i= 0
j= size(A) + 1

do
j = j-1
do
if (A(j) <= x) exit
j = j-1
end do
i = i+1
do
if (A(i) >= x) exit
i = i+1
end do
if (i < j) then
! exchange A(i) and A(j)
temp = A(i)
A(i) = A(j)
A(j) = temp
elseif (i == j) then
marker = i+1
return
else
marker = i
return
endif
end do

end subroutine Partition

end module qsort_c_module


use qsort_c_module
use sort3
implicit none

integer, parameter:: sides = 8
integer, parameter:: trials = 50
integer, parameter :: array_size = trials

integer, parameter:: bins = 50
integer, parameter:: percentile = 95


integer, dimension(sides)::A
integer, dimension(trials)::C
integer, dimension(bins)::D
!! from qsort
integer, dimension(bins)::F

type (address), dimension (array_size) :: data_array

integer:: b, ii, i, counter, &
tab, maxput
real:: harvest, tot

! seed random num generator

CALL init_random_seed

! prime the pump
call random_number(harvest)
b = 3 + nint(10*harvest)
do i=1,b
call random_number(harvest)
print *, i, harvest
end do


! main control

! outer loop is the number of trials
C = 0
do ii=1,trials
tab = 0
A = 0
! inner loop rolls die till all values attained
do
call random_number(harvest)
b = ceiling(harvest*real(sides))
A(b) = A(b) + 1
! count until all outcomes non-zero
counter = 0
do i = 1, sides
if (real(A(i)) > .5) then
counter = counter + 1
end if
end do
tab = tab + 1
if (counter == sides) then
C(ii) = tab
exit
end if
end do !inner
end do !outer

! end main control
print *, "C is", C

! sort into bins
D=0
maxput = bins
do ii =1, trials
if (C(ii) > maxput) then
C(ii) = maxput
end if
D(C(ii))=D(C(ii)) + 1
end do
tot= sum(D)
print *, "total trials=",tot

! determine 95th percentile
tot = 0.01 *trials*real(percentile)
print *, "95th % is", tot

counter = 0
do ii = 1, bins
counter = counter + D(ii)

if (real(counter).ge. tot) then
exit
end if
end do
print *, "95th percentile was in bin number", ii

! equate C with data_array

do i=1,array_size
data_array(i)%zip_code=C(i)
end do

call selection_sort (data_array(1:array_size))
!! paste in qsort

F=C
call QsortC(F)

! output

print *, "quicksorted", F
print *, "selection sorted", data_array

b = nint(tot)
print *, "b=", b
print *, data_array(b)

! end output
contains
SUBROUTINE init_random_seed()
INTEGER :: i, n, clock
INTEGER, DIMENSION(:), ALLOCATABLE :: seed

CALL RANDOM_SEED(size = n)
print *, "n=", n
ALLOCATE(seed(n))

CALL SYSTEM_CLOCK(COUNT=clock)
print *, "clock=", clock

seed = clock + 37 * (/ (i - 1, i = 1, n) /)
CALL RANDOM_SEED(PUT = seed)
print *, "seed= ", seed

DEALLOCATE(seed)
END SUBROUTINE
end program

n= 1
clock= 114586663
seed= 114586663
1 3.715616E-02
2 0.220503
3 0.998302
4 0.563285
5 0.490850
6 0.659474
7 0.634746
C is 18 13 27 20 47
17
24 17 14
12 10 15 10 13 24
21 23 26
45 30 29 14 20 15
19 26 15
30 16 32 12 22 13
13 12 22
13 14 15 21 34 16
17 23 35
17 15 19 13 23
total trials= 50.0000
95th % is 47.5000
95th percentile was in bin number 35
quicksorted 10 10 12 12 12
13 13 13
13 13 13 14 14 14
15 15 15
15 15 16 16 17 17
17 17 18
19 19 20 20 21 21
22 22 23
23 23 24 24 26 26
27 29 30
30 32 34 35 45 47
selection sorted 10 10 12 12
12
13 13 13
13 13 13 14 14 14
15 15 15
15 15 16 16 17 17
17 17 18
19 19 20 20 21 21
22 22 23
23 23 24 24 26 26
27 29 30
30 32 34 35 45 47
b= 48
35

Press RETURN to close window . . .


What is the role of pivot?

Still haven't figured out what pivot does.

--
We are here and it is now. Further than that, all human knowledge is
moonshine. 3
H. L. Mencken
.



Relevant Pages

  • Re: ordering integer array
    ... recursive subroutine selection_sort ... tab, maxput ... real:: harvest, tot ... sort into bins ...
    (comp.lang.fortran)
  • Re: busting sp datatypes
    ... recursive subroutine QsortC ... tab, maxput, diff2, c3, c4 ... real:: harvest, tot, diff, t3, t4 ... sort into bins ...
    (comp.lang.fortran)
  • Re: ordering integer array
    ... recursive subroutine selection_sort ... tab, maxput ... real:: harvest, tot ... sort into bins ...
    (comp.lang.fortran)
  • Re: busting sp datatypes
    ... While the routines I call are sorts, ... recursive subroutine selection_sort ... type:: temp ... sort into bins ...
    (comp.lang.fortran)
  • Re: zipcode selection sort in MR&C
    ... Yes, selection sort shouldn't be implemented with recursion, ... subroutine it can be replaced with a jump to ... a runtime in the swap routine with the assignment of a value to temp. ...
    (comp.lang.fortran)