/
Quicksort.script
139 lines (126 loc) · 2.84 KB
/
Quicksort.script
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
* Create a list of random integers, then sort the list using quicksort.
* It's (java) stack intensive, run with -Xss4m or more.
*/
main() {
runTest(1);
runTest(10);
runTest(100);
runTest(1000);
runTest(10000);
}
runTest(int size) {
print("=== Testing list of size ",size," ===");
test(size);
print("=== test ",size," complete, heap should now be empty ===");
gc();
}
test(int size) {
int n = 0;
object list = null;
while (n < size) {
list = cons(random(0,20000000),list);
n = n + 1;
}
print(" List constructed, sorting ...");
gc();
object sorted = qsort(list);
print(" Sort complete, checking ...");
gc();
checkList(sorted,size);
}
/*
* Utility functions for managing lists of ints
*/
/* List constructor */
object cons(int head, object tail) {
object result = alloc(1,1); // Allocate a list cell
result.int[0] = head;
result.object[0] = tail;
return result;
}
/* List destructors */
int head(object list) {
return list.int[0];
}
object tail(object list) {
return list.object[0];
}
/* Classic recursive append operation */
object append(object part1, object part2) {
if (part1 == null) {
return part2;
} else {
return cons(head(part1),append(tail(part1),part2));
}
}
/* List-based quicksort */
object qsort(object list) {
if (list == null) {
return list;
} else {
int median = head(list);
object part = partition(median,tail(list));
return append(qsort(part.object[0]),cons(median,qsort(part.object[1])));
}
}
/* partition a list around a pivot, returning a pair of lists */
object partition(int pivot,object list) {
object result = alloc(2,0);
result.object[0] = null;
result.object[1] = null;
if (list != null) {
part2(result,pivot,list);
}
return result;
}
/*
* Perform a partition, putting the low elements into parts.object[0],
* and the high elements into parts.object[1]
*/
part2(object parts,int pivot, object list) {
while (list != null) {
int hd = head(list);
if (hd < pivot) {
parts.object[0] = cons(hd,parts.object[0]);
} else {
parts.object[1] = cons(hd,parts.object[1]);
}
list = tail(list);
}
}
/*
* Print a list
*/
printList(object list) {
if (list == null) {
return;
} else {
print (head(list));
printList(tail(list));
}
}
/*
* Sanity check a list - ensure that the elements are in
* monotonic order, and the list is the right length.
*/
checkList(object list, int len) {
int count = 0;
if (list != null) {
int v1 = head(list);
count = 1;
list = tail(list);
while (list != null) {
int v2 = head(list);
count = count + 1;
if (v1 > v2) {
print ("unsorted values in list :(");
}
v1 = v2;
list = tail(list);
}
}
if (count != len) {
print ("list has changed length (expected ",len," found ",count,")");
}
}