Introduction to Programming in ATS: | ||
---|---|---|
<<< Previous | Parametric Polymorphism | Next >>> |
Mergesort is simple sorting algorithm that is guaranteed to be log-linear. It is stable in the sense that the order of two equal elements always stay the same after sorting. I give as follows a typical functional style of implementation of mergesort on lists.
First, let us introduce abbreviations for the list constructors list0_nil and list0_cons:
#define nil list0_nil // writing [nil] for list0_nil #define :: list0_cons // writing [::] for list0_cons #define cons list0_cons // writing [cons] for list0_cons |
We next implement a function template merge to merge two given ordered lists into a single ordered one:
typedef lte (a:t@ype) = (a, a) -> bool fun{a:t@ype} merge ( xs: list0 a, ys: list0 a, lte: lte a ) : list0 a = case+ xs of | x :: xs1 => ( case+ ys of | y :: ys1 => if x \lte y then x :: merge (xs1, ys, lte)) else y :: merge (xs, ys1, lte)) // end of [if] | nil () => xs ) // end of [::] | nil () => ys // end of [merge] |
The following function template mergesort implements the standard mergesort algorithm:
fun{a:t@ype} mergesort (xs: list0 a, lte: lte a): list0 a = let // fun msort ( xs: list0 a, n: int, lte: lte a ) : list0 a = if n >= 2 then split (xs, n, lte, n/2, nil) else xs and split ( xs: list0 a, n: int, lte: lte a, i: int, xsf: list0 a ) : list0 a = if i > 0 then let val- cons (x, xs) = xs in split (xs, n, lte, i-1, cons (x, xsf)) end else let val xsf = list0_reverse<a> (xsf) // make sorting stable! val xsf = msort (xsf, n/2, lte) and xs = msort (xs, n-n/2, lte) in merge (xsf, xs, lte) end // end of [if] // val n = list0_length<a> (xs) // in msort (xs, n, lte) end // end of [mergesort] |
Note that the function template merge is not tail-recursive as the call to merge in its body is not a tail-call. This is a serious problem in practice: It is almost certain that a stack overflow is to occur if the above implementation of mergesort is employed to sort a list that is very long (e.g., containing 1,000,000 elements or more). I will later give a tail-recursive implementation of the merge function in ATS that makes use of linear types.
Please find the entire code in this section plus some additional code for testing on-line.
<<< Previous | Home | Next >>> |
Example: Function Templates on Lists | Up | Summary |