-
Notifications
You must be signed in to change notification settings - Fork 0
/
sorts.mp
75 lines (71 loc) · 1.8 KB
/
sorts.mp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
% Toby Thurston -- 10 Jan 2017
%
% Some simple sorting routines
% The key technique here is to pass the array name as a `suffix` rather than an `expr`.
% This allows you to index the array whose name you pass in (which is what we need).
%
% Arrays are assumed to have numeric values and non-negative integer indexes, starting at 0 with
% no missing values.
%
% Note also to `save` variables *before* re-declaring them.
%
%
% Quicksort requires you to pass lo, hi indexes, so you need to know
% how long your array is before you start
vardef quicksort(suffix A)(expr lo, hi) =
save p; numeric p;
if lo < hi:
p := _partition(A, lo, hi);
quicksort(A, lo, p);
quicksort(A, p+1, hi);
fi
enddef;
% using Hoare's original two pointer scheme
vardef _partition(suffix A)(expr lo, hi) =
save i,j,t,pivot;
numeric pivot,t; % values, we are sorting numbers...
numeric i,j; % indexes
pivot := A[lo];
i := lo - 1;
j := hi + 1;
forever:
forever:
i := i + 1;
exitif A[i] >= pivot;
endfor
forever:
j := j - 1;
exitif A[j] <= pivot;
endfor
exitif i >= j;
t := A[i]; A[i] := A[j]; A[j] := t;
endfor
j
enddef;
vardef insertionsort(suffix A) =
save i,j,t;
numeric t; % values, we are sorting numbers
numeric i,j; % indexes
i := 0;
forever:
i := i+1;
exitif not known A[i];
j := i;
forever:
exitif j <= 0;
exitif A[j-1] <= A[j];
t := A[j-1]; A[j-1] := A[j]; A[j] := t;
j := j - 1;
endfor
endfor
enddef;
vardef array_length(suffix A) =
save i;
numeric i;
i := 0;
forever:
i := i+1;
exitif not known A[i];
endfor
i
enddef;