innerSort:
PROC [head:
LORA, max:
NAT]
RETURNS [new, next:
LORA] = {
First, grab the first pair of elements off the head of the list and make sure that they are sorted. If there is only one element, we return it immediately. If there are only two elements in the list first sort them, then return them.
mid: LORA ¬ (new ¬ head).rest;
IF mid = NIL THEN RETURN;
next ¬ mid.rest;
IF compareProc[new.first, mid.first] = greater
THEN {
The first two nodes are in the wrong order, so swap them, leaving new pointing at the lesser of the two, and mid pointing at the greater.
mid.rest ¬ new; new ¬ mid; mid ¬ head;
};
mid.rest ¬ NIL;
IF next = NIL THEN RETURN;
Second, grab the second pair of elements off the list. We have already checked, and there is at least one.
next ¬ (mid ¬ next).rest;
IF next #
NIL
THEN {
There are two elements for the second pair, so we need to put them in order.
temp: LORA ¬ next;
next ¬ temp.rest;
temp.rest ¬ NIL;
IF compareProc[mid.first, temp.first] = greater
THEN {
The first two nodes are in the wrong order, so swap them.
mid.rest ¬ NIL; temp.rest ¬ mid; mid ¬ temp}
};
Third, merge the two lead lists. If this exhausts the original list, then return.
new ¬ Merge[new, mid, compareProc];
IF next = NIL THEN RETURN;
Finally, build up the tree by progressively building small lists and merging them into larger lists. The size doubles at each level. We start with new holding onto a list of 4 elements, and next holding onto the remainder of the list.
FOR depth:
NAT
IN [2..max)
DO
[mid, next] ¬ innerSort[next, depth];
new ¬ Merge[new, mid, compareProc];
IF next = NIL THEN RETURN;
ENDLOOP;
};