3 (* This is tmergesort taken from Paulson
's book
, page
99 *)
5 (* The merge function has been modified slightly
, to
6 traverse
and rebuild both arguments fully
, even when
7 the one argument is empty
. This ensures that both
8 recursive calls
of tmergesort
in itself can put their
9 results
in regions
local to the body
of tmergesort
.
11 One can show that the maximum number
of live list elements
12 is
3n
, where n is the number
of elements to be sorted
.
13 For n
=50000 this should give an approximate memory usage
of
14 3 * 50.000 list elements
* 5 words
/list element
* 4 bytes
/word=
15 3Mb
. The actual memory
usage (run24d
) is
4.5Mb
. The remaining
16 1.5Mb is probably largely due to the fact that merge puts
17 stuff on the
stack (as it is not tail recursive
).
21 exception Take
and Drop
24 |
take(n
, x
::xs
) = x
::take(n
-1, xs
)
25 |
take(n
, []) = raise Take
28 |
drop(n
, x
::xs
) = drop(n
-1, xs
)
29 |
drop(n
, []) = raise Drop
31 fun digit n
= chr(ord #
"0" + n
)
34 if n
>=0 andalso n
<=9 then digit n
:: acc
35 else digits (n
div 10, digit(n
mod 10) :: acc
)
36 fun int_to_string(n
) = implode(digits(n
,[#
"\n"]))
47 fun randlist(n
,seed
,tail
)=
48 if n
=0 then (seed
,tail
)
49 else randlist(n
-1, nextrand seed
, seed
::tail
)
53 |
length (_
::xs
) = 1+length xs
55 fun merge([], ys
) = (ys
:int list
)@
[]
56 |
merge(xs
, []) = xs @
[]
57 |
merge(l
as x
::xs
, r
as y
:: ys
) =
58 if x
<= y
then x
::merge(xs
, r
)
61 fun tmergesort
[] = []
62 | tmergesort
[x
] = [x
]
64 let val k
= length xs
div 2
65 in merge(tmergesort(take(k
, xs
)),
66 tmergesort(drop(k
, xs
)))
73 val xs
= snd(randlist(n
,1,[]))
74 val _
= print
"\n List generated\n"
75 fun report msg
= print(msg^
"\n")
77 report
"Doing tmergesort...";
79 report("Sorted " ^ int_to_string n ^
" numbers\n")