Tutorial 8

🔗

Linked List (Ordered)

9618 A-Level


i

For linked lists, the following operations are required for A2: insert at start, end and ordered position, remove node, search and output of a linked list

It may be useful to search (CTRL + F) for "linked list" questions in the (combined) past papers

If you find any bugs/edge cases in this code, please contact me

1

Ordered Linked List

Below shows the full code for an ordered linked list

TYPE Node DECLARE data, pointer : INTEGER ENDTYPE DECLARE list : ARRAY[1:5] OF Node DECLARE freeListPointer, headPointer : INTEGER CALL Reset() CALL AddNode(3) CALL AddNode(2) CALL AddNode(5) CALL AddNode(1) CALL AddNode(4) CALL RemoveNode(5) CALL RemoveNode(1) CALL RemoveNode(3) CALL AddNode(7) CALL AddNode(6) CALL AddNode(8) FOR n ← 0 TO 8 OUTPUT n, ": ", Search(n) NEXT n CALL OutputListArray() CALL OutputListPretty() PROCEDURE Reset() DECLARE currentPointer : INTEGER //create the free list - all nodes have data of -1 and point to the subsequent node FOR currentPointer ← 1 TO LENGTH(list) - 1 list[currentPointer].data ← -1 list[currentPointer].pointer ← currentPointer + 1 NEXT currentPointer list[LENGTH(list)].data ← -1 list[LENGTH(list)].pointer ← -1 //last node points to null pointer headPointer ← -1 //head is null = empty list freeListPointer ← 1 //free list starts at index 1 ENDPROCEDURE //add node at correct position (in ascending order) PROCEDURE AddNode(data : INTEGER) DECLARE currentPointer, previousPointer, newNodePointer : INTEGER //check list not full IF freeListPointer <> -1 THEN //use first node from free list to be new node newNodePointer ← freeListPointer list[newNodePointer].data ← data //add data to new node freeListPointer ← list[freeListPointer].pointer //update freeListPointer to point to next available free list node //start searching from beginning of list currentPointer ← headPointer previousPointer ← -1 //while not end of life and not found position to add WHILE currentPointer <> -1 AND list[currentPointer].data < data DO previousPointer ← currentPointer currentPointer ← list[currentPointer].pointer //go to next node ENDWHILE //if insert at start IF previousPointer = -1 THEN list[newNodePointer].pointer ← headPointer //new node should point to previous first node headPointer ← newNodePointer //set new node as being the first node ELSE list[newNodePointer].pointer ← list[previousPointer].pointer //make new node point to next node list[previousPointer].pointer ← newNodePointer //make previous node point to new node ENDIF OUTPUT "Added: ", data ELSE OUTPUT "List full" ENDIF ENDPROCEDURE //find an element in an ordered linked list FUNCTION Search(data : INTEGER) RETURNS BOOLEAN DECLARE currentPointer : INTEGER //start searching from beginning currentPointer ← headPointer //search while not at end of list and current node's data is <= search data - since otherwise, we have passed where that value would be if it existed, hence can stop searching WHILE currentPointer <> -1 AND list[currentPointer].data <= data DO //if found IF list[currentPointer].data = data THEN RETURN TRUE ENDIF currentPointer ← list[currentPointer].pointer //go to next node ENDWHILE //if searched all possible positions on not found node, then it doesn't exist RETURN FALSE ENDFUNCTION PROCEDURE RemoveNode(data : INTEGER) DECLARE currentPointer, previousPointer : INTEGER DECLARE found : BOOLEAN found ← FALSE //not found node we're removing currentPointer ← headPointer //start searching from head previousPointer ← headPointer //can't use -1, so also start from head //while not end of list, not removed node and not passed node's possible position WHILE currentPointer <> -1 AND found = FALSE AND list[currentPointer].data <= data DO //if found IF list[currentPointer].data = data THEN //set previous node's pointer to pointer to this node's pointer - effectivelly 'cutting out' the current node by bypassing it list[previousPointer].pointer ← list[currentPointer].pointer //if removing the first element IF currentPointer = headPointer THEN headPointer ← list[currentPointer].pointer //make the head point to the 2nd node (might be null pointer if only 1 node) ENDIF //add removed node to beginning of free list list[currentPointer].pointer ← freeListPointer freeListPointer ← currentPointer OUTPUT "Removed: ", data found ← TRUE ENDIF previousPointer ← currentPointer //set previous pointer for next loop iteration currentPointer ← list[currentPointer].pointer //go to next node ENDWHILE IF found = FALSE THEN OUTPUT "Didn't remove ", data, " - it doesn't exist in list" ENDIF ENDPROCEDURE PROCEDURE OutputList() DECLARE currentPointer : INTEGER currentPointer ← headPointer //loop while nodes are remaining WHILE currentPointer <> -1 DO OUTPUT list[currentPointer].data currentPointer ← list[currentPointer].pointer //go to next node ENDWHILE ENDPROCEDURE PROCEDURE OutputListPretty() DECLARE line : STRING DECLARE currentPointer : INTEGER OUTPUT "--- List ---" currentPointer ← headPointer line ← "" //loop while nodes are remaining WHILE currentPointer <> -1 DO line ← line & NUM_TO_STR(list[currentPointer].data) currentPointer ← list[currentPointer].pointer //go to next node //add "->" seperator if not last node IF currentPointer <> -1 THEN line ← line & " -> " ENDIF ENDWHILE OUTPUT line OUTPUT "" ENDPROCEDURE //a "helper" procedure to display the contents of the linked list array for debugging/understanding - note, you won't need to write this in the exam (unless they specifically ask you to create a helper method to visualise the array contents) PROCEDURE OutputListArray() DECLARE index : INTEGER OUTPUT "Head Pointer: ", headPointer OUTPUT "Free List Pointer: ", freeListPointer //index, data, pointer OUTPUT " I | D | P" FOR index ← 1 TO LENGTH(list) OUTPUT " ", index, " | ", list[index].data, " | ", list[index].pointer NEXT index ENDPROCEDURE

Extension details/answers will be added: