Sorting algorithms on lists #
In this file we define List.Sorted r l
to be an alias for Pairwise r l
. This alias is preferred
in the case that r
is a <
or ≤
-like relation. Then we define two sorting algorithms:
List.insertionSort
and List.mergeSort
, and prove their correctness.
The predicate List.Sorted
#
Equations
The list List.ofFn f
is strictly sorted with respect to (· ≤ ·)
if and only if f
is
strictly monotone.
The list obtained from a monotone tuple is sorted.
Insertion sort #
orderedInsert a l
inserts a
into l
at such that
orderedInsert a l
is sorted if l
is.
Equations
- List.orderedInsert r a [] = [a]
- List.orderedInsert r a (b :: l) = if r a b then a :: b :: l else b :: List.orderedInsert r a l
Instances For
insertionSort l
returns l
sorted using the insertion sort algorithm.
Equations
- List.insertionSort r [] = []
- List.insertionSort r (b :: l) = List.orderedInsert r b (List.insertionSort r l)
Instances For
An alternative definition of orderedInsert
using takeWhile
and dropWhile
.
If l
is already List.Sorted
with respect to r
, then insertionSort
does not change
it.
The list List.insertionSort r l
is List.Sorted
with respect to r
.
Merge sort #
Split l
into two lists of approximately equal length.
split [1, 2, 3, 4, 5] = ([1, 3, 5], [2, 4])
Equations
- List.split [] = ([], [])
- List.split (b :: l) = match List.split l with | (l₁, l₂) => (b :: l₂, l₁)
Instances For
Merge two sorted lists into one in linear time.
merge [1, 2, 4, 5] [0, 1, 3, 4] = [0, 1, 1, 2, 3, 4, 4, 5]
Equations
- List.merge r [] x = x
- List.merge r x [] = x
- List.merge r (a :: l) (b :: l') = if r a b then a :: List.merge r l (b :: l') else b :: List.merge r (a :: l) l'
Instances For
Implementation of a merge sort algorithm to sort a list.
Equations
- List.mergeSort r [] = []
- List.mergeSort r [a] = [a]
- List.mergeSort r (a :: b :: l) = List.merge r (List.mergeSort r (List.split (a :: b :: l)).1) (List.mergeSort r (List.split (a :: b :: l)).2)