1 (* Copyright (C
) 1999-2005 Henry Cejtin
, Matthew Fluet
, Suresh
2 * Jagannathan
, and Stephen Weeks
.
4 * MLton is released under a BSD
-style license
.
5 * See the file MLton
-LICENSE for details
.
11 val make
: ('a
* 'a
-> bool) -> {isSorted
: 'a t
-> bool,
12 merge
: 'a t
* 'a t
-> 'a t
,
18 fun isSorted (l
, le
) = #
isSorted (make le
) l
19 fun merge (l
, l
', le
) = #
merge (make le
) (l
, l
')
20 fun sort (l
, le
) = #
sort (make le
) l
23 structure MergeSortList
: MERGE_SORT
=
27 (* This is a variant
of mergesort that runs
in O (n log n
) time
. *)
28 fun make (op <= : 'a
* 'a
-> bool) =
30 fun assert f
= Assert
.assert ("MergeSort.assert", f
)
39 | x
' :: l
=> x
<= x
' andalso loop (x
', l
)
43 (assert (fn () => isSorted l1
andalso isSorted l2
)
47 |
(x1
:: l1
', x2
:: l2
') =>
49 then x1
:: merge (l1
', l2
)
50 else x2
:: merge (l1
, l2
')))
54 val _
= assert (fn () => length l
< Int.pow (2, numBuckets
) - 1)
55 val a
: 'a list array
= Array
.new (numBuckets
, [])
57 assert (fn () => Array
.foralli (a
, fn (i
, l
) =>
60 | _
=> (length l
= Int.pow (2, i
)
62 fun mergeIn (i
: int, l
: 'a list
): unit
=
63 (assert (fn () => length l
= Int.pow (2, i
))
64 ; (case Array
.sub (a
, i
) of
65 [] => Array
.update (a
, i
, l
)
66 | l
' => (Array
.update (a
, i
, [])
67 ; mergeIn (i
+ 1, merge (l
, l
')))))
68 val _
= List.foreach (l
, fn x
=> mergeIn (0, [x
]))
69 val l
= Array
.fold (a
, [], fn (l
, l
') =>
73 val _
= assert (fn () => isSorted l
)
82 structure MergeSortVector
: MERGE_SORT
=
84 (type 'a t
= 'a vector
88 fun isSorted v
= Vector.isSorted (v
, op <=)
91 val _
= Assert
.assert ("MergeSortVector.merge: pre", fn () =>
93 andalso isSorted (v
', op <=))
102 (* 0 <= i
<= n
andalso 0 <= i
' <= n
' *)
107 val res
= sub (v
', i
')
121 val a
' = sub (v
', i
')
125 else (Int.inc r
'; a
')
128 val v
= tabulate (n
+ n
', fn _
=> next ())
129 val _
= Assert
.assert ("MergeSortVector.merge: post", fn () =>
138 if isSorted (v
, op <=)
148 let val r
= ref start
157 in merge (get (m
', 0), get (m
, 1), op <=)
160 val _
= Assert
.assert ("MergeSortVector.sort", fn () =>
166 {isSorted
= isSorted
,