MODULE IntegerList;
IMPORT
Node, ObjectOrientedLists, In, OutExt;
TYPE
IntegerNode = POINTER TO IntegerNodeDesc;
IntegerNodeDesc = RECORD
(Node.DoublyLinkedNodeDesc)
value: INTEGER;
END;
VAR
input, list: ObjectOrientedLists.CircularDoublyLinkedList;
PROCEDURE (this: IntegerNode) Print*();
BEGIN
OutExt.Int(this^.value, 0);
OutExt.Ln;
END Print;
PROCEDURE BubbleSort*;
VAR
currentNode, lastNode: Node.Node;
switched: BOOLEAN;
BEGIN
(* we start by iterating through the entire list, decreasing the size of the unsorted part by bubbling the largest elements *)
lastNode := list^.ReturnLastNode();
(* we only continue with sorting if there has been a switch, otherwise the list is already in order *)
switched := TRUE;
WHILE switched DO
(* the unsorted part is at the beginning of the list *)
currentNode := list^.head^.next;
(* we put the boolean on false, and if there is an exchange, we'll set it on true for this iteration *)
switched := FALSE;
(* we loop through the list until we encounter the last unsorted element *)
WHILE currentNode # lastNode DO
IF currentNode(IntegerNode)^.value > currentNode^.next(IntegerNode)^.value THEN
(* if we try to exchange a node at the end of our list, things go wrong *)
IF currentNode^.next = lastNode THEN
list^.NodeExchange(currentNode, lastNode);
lastNode := currentNode;
ELSE
list^.NodeExchange(currentNode, currentNode^.next);
END;
(* there has been a switch, so this must be true *)
switched := TRUE;
ELSE
(* there was no need for switching, we look at the next element *)
currentNode := currentNode^.next;
END;
END;
(* we can decrease the size of the unsorted part *)
lastNode := list^.ReturnPreviousNode(lastNode);
END;
OutExt.String("De lijst is gesorteerd door middel van een bubble sort.");
OutExt.Ln;
END BubbleSort;
PROCEDURE SelectionSort*;
VAR
currentNode, lastSortedNode, smallestNode: Node.Node;
BEGIN
(* obviously, the list starts unsorted *)
lastSortedNode := list^.head;
(* lastSortedNode will indicate which node is currently the last sorted, so lastSortedNode will be the last node of the list when it's sorted *)
WHILE lastSortedNode^.next # list^.head DO
(* the node next to lastSortedNode is the first node of the part of the list where we will look for the smallest node *)
currentNode := lastSortedNode^.next;
(* we start with the first unsorted node as smallest node *)
smallestNode := currentNode;
(* we loop through the unsorted part, until the end of the list *)
WHILE currentNode # list^.head DO
IF currentNode(IntegerNode)^.value < smallestNode(IntegerNode)^.value THEN
(* currentNoe is smaller than the former smallest node, so we change smallestNode *)
smallestNode := currentNode;
END;
currentNode := currentNode^.next;
END;
list^.NodeExchange(lastSortedNode^.next, smallestNode);
lastSortedNode := smallestNode;
END;
OutExt.String("De lijst is gesorteerd volgens een selection sort.");
OutExt.Ln;
END SelectionSort;
PROCEDURE Initiate*;
VAR
integerNode: IntegerNode;
integer: INTEGER;
BEGIN
OutExt.Open();
OutExt.Clear();
NEW(input);
NEW(list);
input^.Init();
list^.Init();
In.Open();
In.Int(integer);
WHILE In.Done DO
NEW(integerNode);
integerNode^.value := integer;
input^.NodeInsert(integerNode);
In.Int(integer);
END;
OutExt.String("De lijst is ingelezen.");
OutExt.Ln;
list^ := input^;
END Initiate;
PROCEDURE Print*;
BEGIN
input^.Print();
OutExt.String("Het resultaat van de uitgevoerde acties:");
OutExt.Ln;
list^.Print();
END Print;
PROCEDURE Reset*;
BEGIN
OutExt.String("De lijst is overschreven door de (onbewerkte) input.");
OutExt.Ln;
list := input;
END Reset;
BEGIN
END IntegerList.