home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / euphor10.zip / ALLSORTS.EX next >
Text File  |  1993-06-15  |  8KB  |  372 lines

  1.         ----------------------------------------
  2.         -- Sorting Algorithms in Euphoria     --
  3.         -- These routines will sort sequences --
  4.         -- of general Euphoria objects          --
  5.         ----------------------------------------
  6. without type_check
  7.  
  8. constant MAX = 4800
  9. constant TRUE = 1, FALSE = 0
  10. constant CHECK_RESULTS = FALSE
  11.  
  12. integer hybrid_limit
  13.  
  14. type natural(integer x)
  15.     return x >= 0
  16. end type
  17.  
  18. type file_number(integer x)
  19.     return x >= -1
  20. end type
  21.  
  22. function simple_sort(sequence x)
  23. -- put x into ascending order
  24. -- using a very simple sort
  25. object temp
  26.  
  27.     for i = 1 to length(x) - 1 do
  28.     for j = i + 1 to length(x) do
  29.         if compare(x[j],x[i]) < 0 then
  30.         temp = x[j]
  31.         x[j] = x[i]
  32.         x[i] = temp
  33.         end if
  34.     end for
  35.     end for
  36.     return x
  37. end function
  38.  
  39.  
  40. function bubble_sort(sequence x)
  41. -- put x into ascending order
  42. -- using bubble sort
  43. object temp
  44. natural flip, limit
  45.  
  46.     flip = length(x)
  47.     while flip > 0 do
  48.     limit = flip
  49.     flip = 0
  50.     for i = 1 to limit - 1 do
  51.         if compare(x[i+1], x[i]) < 0 then
  52.         temp = x[i+1]
  53.         x[i+1] = x[i]
  54.         x[i] = temp
  55.         flip = i
  56.         end if
  57.     end for
  58.     end while
  59.     return x
  60. end function
  61.  
  62. function insertion_sort(sequence x)
  63. -- put x into ascending order
  64. -- using insertion sort
  65. object temp
  66. natural final
  67.  
  68.     for i = 2 to length(x) do
  69.     temp = x[i]
  70.     final = 1
  71.     for j = i-1 to 1 by -1 do
  72.         if compare(temp, x[j]) < 0 then
  73.         x[j+1] = x[j]
  74.         else
  75.         final = j + 1
  76.         exit
  77.         end if
  78.     end for
  79.     x[final] = temp
  80.     end for
  81.     return x
  82. end function
  83.  
  84. function shell_sort(sequence x)
  85. -- Shell sort based on insertion sort
  86.  
  87.     integer gap, j, first, last
  88.     object tempi, tempj
  89.  
  90.     last = length(x)
  91.     gap = floor(last / 3) + 1
  92.     while TRUE do
  93.     first = gap + 1
  94.     for i = first to last do
  95.         tempi = x[i]
  96.         j = i - gap
  97.         while TRUE do
  98.         tempj = x[j]
  99.         if compare(tempi, tempj) >= 0 then
  100.             j = j + gap
  101.             exit
  102.         end if
  103.         x[j+gap] = tempj
  104.         if j <= gap then
  105.             exit
  106.         end if
  107.         j = j - gap
  108.         end while
  109.         x[j] = tempi
  110.     end for
  111.     if gap = 1 then
  112.         return x
  113.     else
  114.         gap = floor(gap / 3) + 1
  115.     end if
  116.     end while
  117. end function
  118.  
  119.  
  120. global function quick_sort(sequence x)
  121. -- put x into ascending order
  122. -- using recursive quick sort
  123.     natural n, last, midval, temp
  124.  
  125.     n = length(x)
  126.     if n < 2 then
  127.     return x -- already sorted (trivial case)
  128.     end if
  129.  
  130.     midval = x[(n + 1) / 2]
  131.     x[(n + 1) / 2] = x[1]
  132.  
  133.     last = 1
  134.     for i = 2 to n do
  135.     if compare(x[i], midval) < 0 then
  136.         last = last + 1
  137.         temp = x[last]  x[last] = x[i]  x[i] = temp
  138.     end if
  139.     end for
  140.  
  141.     return quick_sort(x[2..last]) & {midval} & quick_sort(x[last+1..n])
  142. end function
  143.  
  144.  
  145. global function hybrid_sort(sequence x)
  146. -- put x into ascending order
  147. -- using recursive quick sort
  148. -- but call insertion sort for short sequences
  149. -- This is set up to sort any kind of object
  150.     natural n, last, midpt
  151.     object midval, temp
  152.  
  153.     n = length(x)
  154.     if n < hybrid_limit then
  155.     return insertion_sort(x)
  156.     end if
  157.  
  158.     midpt = floor((n + 1) / 2)
  159.     midval = x[midpt]
  160.     x[midpt] = x[1]
  161.  
  162.     last = 1
  163.     for i = 2 to n do
  164.     if compare(x[i], midval) < 0 then
  165.         last = last + 1
  166.         temp = x[last]  x[last] = x[i]  x[i] = temp
  167.     end if
  168.     end for
  169.  
  170.     return hybrid_sort(x[2..last]) & {midval} & hybrid_sort(x[last+1..n])
  171. end function
  172.  
  173. sequence x
  174.  
  175. procedure g_insertion_sort()
  176. -- put global variable x into ascending order
  177. -- using insertion sort of general objects
  178. object temp
  179. natural final
  180.  
  181.     for i = 2 to length(x) do
  182.     temp = x[i]
  183.     final = 1
  184.     for j = i-1 to 1 by -1 do
  185.         if compare(temp, x[j]) < 0 then
  186.         x[j+1] = x[j]
  187.         else
  188.         final = j + 1
  189.         exit
  190.         end if
  191.     end for
  192.     x[final] = temp
  193.     end for
  194. end procedure
  195.  
  196. procedure best_sort(natural m, natural n)
  197. -- put x into ascending order
  198. -- using recursive quick sort
  199.     natural last, midpt
  200.     object midval, temp
  201.  
  202.     if n - m < 20 then -- 10 or 20
  203.     return
  204.     end if
  205.  
  206.     midpt = floor((m + n) / 2)
  207.     midval = x[midpt]
  208.     x[midpt] = x[m]
  209.  
  210.     last = m
  211.     for i = m+1 to n do
  212.     if compare(x[i], midval) < 0 then
  213.         last = last + 1
  214.         temp = x[last]  x[last] = x[i]  x[i] = temp
  215.     end if
  216.     end for
  217.     x[m] = x[last]
  218.     x[last] = midval
  219.     best_sort(m, last-1)
  220.     best_sort(last+1, n)
  221. end procedure
  222.  
  223. global function great_sort(sequence a)
  224. -- avoids dynamic storage allocation - just passes indexes into
  225. -- a global sequence
  226. -- not much better than hybrid_sort which makes full use of dynamic
  227. -- storage allocation
  228. -- note that we only partition down to a certain degree, then do an
  229. -- insertion sort which will run fast because things are roughly in order
  230. -- see Knuth for the details
  231.     x = a
  232.     best_sort(1, length(x))
  233.     g_insertion_sort()
  234.     return x
  235. end function
  236.  
  237. global function merge_sort(sequence x)
  238. -- put x into ascending order
  239. -- using recursive merge sort
  240.     natural n
  241.     sequence x1, x2, newx
  242.  
  243.     n = length(x)
  244.     if n < 2 then
  245.     return x
  246.     end if
  247.  
  248.     x1 = merge_sort(x[1..n/2])
  249.     x2 = merge_sort(x[n/2+1..n])
  250.     newx = {}
  251.     while length(x1) > 0 and length(x2) > 0 do
  252.     if compare(x1[1], x2[1]) < 0 then
  253.         newx = append(newx, x1[1])
  254.         x1 = x1[2..length(x1)]
  255.     else
  256.         newx = append(newx, x2[1])
  257.         x2 = x2[2..length(x2)]
  258.     end if
  259.     end while
  260.     newx = newx & x1 & x2 -- one will be empty
  261.     return newx
  262. end function
  263.  
  264. procedure check_results(sequence sdata, sequence data)
  265. -- compare results with another sort to make sure they are correct
  266.     if CHECK_RESULTS then
  267.         if compare(sdata, shell_sort(data)) != 0 then
  268.         puts(2, "\nabort!\n")
  269.         print(2, 1/0)
  270.         end if
  271.     end if
  272. end procedure
  273.  
  274. procedure all_sorts()
  275. -- test all sorting routines over a range of numbers of items
  276.  
  277.     file_number printer
  278.     natural nitems, iterations
  279.     atom t0, t
  280.     sequence data, sdata
  281.  
  282.     printer = 1   -- open("PRN", "w")
  283.     nitems = 5
  284.     while nitems <= MAX do
  285.     -- get several sets of data of length nitems
  286.     iterations = floor(MAX/nitems)
  287.     if iterations > 500 then
  288.         iterations = 500
  289.     end if
  290.     printf(printer, "\ntime (sec.) to sort %d items (averaged over %d trials)\n",
  291.             {nitems, iterations})
  292.  
  293.     data = rand(repeat(repeat(nitems, nitems), iterations))
  294.     t0 = time()
  295.     for i = 1 to iterations do
  296.         sdata = bubble_sort(data[i])
  297.         check_results(sdata, data[i])
  298.     end for
  299.     t = time() - t0
  300.     printf(printer, "bubble sort   %9.4f\n", t/iterations)
  301.  
  302.     t0 = time()
  303.     for i = 1 to iterations do
  304.         sdata =  simple_sort(data[i])
  305.         check_results(sdata, data[i])
  306.     end for
  307.     t = time() - t0
  308.     printf(printer, "simple sort   %9.4f\n", t/iterations)
  309.  
  310.     t0 = time()
  311.     for i = 1 to iterations do
  312.         sdata = insertion_sort(data[i])
  313.         check_results(sdata, data[i])
  314.     end for
  315.     t = time() - t0
  316.     printf(printer, "insertion sort%9.4f\n", t/iterations)
  317.  
  318.     t0 = time()
  319.     for i = 1 to iterations do
  320.         sdata = shell_sort(data[i])
  321.         check_results(sdata, data[i])
  322.     end for
  323.     t = time() - t0
  324.     printf(printer, "shell sort    %9.4f\n", t/iterations)
  325.  
  326.     t0 = time()
  327.     for i = 1 to iterations do
  328.         sdata = merge_sort(data[i])
  329.         check_results(sdata, data[i])
  330.     end for
  331.     t = time() - t0
  332.     printf(printer, "merge sort    %9.4f\n", t/iterations)
  333.  
  334.     t0 = time()
  335.     for i = 1 to iterations do
  336.         sdata = quick_sort(data[i])
  337.         check_results(sdata, data[i])
  338.     end for
  339.     t = time() - t0
  340.     printf(printer, "quick sort    %9.4f\n", t/iterations)
  341.  
  342.     for hl = 20 to 20 by 2 do
  343.         hybrid_limit = hl
  344.         t0 = time()
  345.         for i = 1 to iterations do
  346.         sdata = hybrid_sort(data[i])
  347.         check_results(sdata, data[i])
  348.         end for
  349.         t = time() - t0
  350.         printf(printer, "hybrid sort-%d%9.4f\n", {hybrid_limit,t/iterations})
  351.     end for
  352.  
  353.     for hl = 20 to 20 by 2 do
  354.         hybrid_limit = hl
  355.         t0 = time()
  356.         for i = 1 to iterations do
  357.         sdata = great_sort(data[i])
  358.         check_results(sdata, data[i])
  359.         end for
  360.         t = time() - t0
  361.         printf(printer, "great sort-%d %9.4f\n", {hybrid_limit,t/iterations})
  362.     end for
  363.  
  364.     puts(1, "\nPress Enter to continue, control-c to quit")
  365.     if length(gets(0)) then
  366.     end if
  367.     nitems = nitems * 2
  368.     end while
  369. end procedure
  370.  
  371. all_sorts()
  372.