Advanced Algorithms and Recursion: Question 2

Syllabus 19.1

Structured A2 8 marks

A software company implements two Abstract Data Types (ADTs) using arrays, each with pointer variables to keep track of the current position.

An undo stack for a text editor stores the names of formatting actions the user has applied, so that the most recently applied action can be undone first. It is implemented using this pseudocode:

DECLARE MaxSize : INTEGER
CONSTANT MaxSize ← 5
DECLARE ActionStack : ARRAY[1:MaxSize] OF STRING
DECLARE Top : INTEGER
Top ← 0

PROCEDURE Push(Item : STRING)
    IF Top = MaxSize THEN
        OUTPUT "Stack full"
    ELSE
        Top ← Top + 1
        ActionStack[Top] ← Item
    ENDIF
ENDPROCEDURE

FUNCTION Pop() RETURNS STRING
    DECLARE Removed : STRING
    IF Top = 0 THEN
        OUTPUT "Stack empty"
    ELSE
        Removed ← ActionStack[Top]
        Top ← Top - 1
        RETURN Removed
    ENDIF
ENDFUNCTION

(a) Starting from an empty stack (Top = 0), these calls are made in order:

CALL Push("Bold")
CALL Push("Italic")
CALL Push("Underline")
LastAction ← Pop()
CALL Push("ResizeFont")
NextAction ← Pop()

Complete a trace showing the value of Top after each call, and state the final values of LastAction and NextAction. [4]

A print queue for a shared office printer stores the names of documents waiting to print, so that documents are printed in the order they were sent. It is implemented using this pseudocode:

DECLARE MaxSize : INTEGER
CONSTANT MaxSize ← 5
DECLARE PrintQueue : ARRAY[1:MaxSize] OF STRING
DECLARE Front, Rear : INTEGER
Front ← 0
Rear ← 0

PROCEDURE Enqueue(Item : STRING)
    IF Rear = MaxSize THEN
        OUTPUT "Queue full"
    ELSE
        Rear ← Rear + 1
        PrintQueue[Rear] ← Item
        IF Front = 0 THEN
            Front ← 1
        ENDIF
    ENDIF
ENDPROCEDURE

FUNCTION Dequeue() RETURNS STRING
    DECLARE Removed : STRING
    IF (Front = 0) OR (Front > Rear) THEN
        OUTPUT "Queue empty"
    ELSE
        Removed ← PrintQueue[Front]
        Front ← Front + 1
        RETURN Removed
    ENDIF
ENDFUNCTION

(b) Starting from an empty queue (Front = 0, Rear = 0), these calls are made in order:

CALL Enqueue("Report.docx")
CALL Enqueue("Invoice.pdf")
CALL Enqueue("Timetable.xlsx")
FirstPrinted ← Dequeue()
CALL Enqueue("Poster.png")
SecondPrinted ← Dequeue()

Complete a trace showing the values of Front and Rear after each call, and state the final values of FirstPrinted and SecondPrinted. [4]

Show worked solution Hide worked solution

Worked solution

Part (a): Tracing the stack (push and pop)

A stack is Last-In-First-Out (LIFO): Push adds an item above the current Top position, and Pop removes the item currently at Top.

CallTop beforeWhat happensTop afterStack contents (index : value)
Push("Bold")0Top ← 1; ActionStack[1] ← "Bold"11:Bold
Push("Italic")1Top ← 2; ActionStack[2] ← "Italic"21:Bold, 2:Italic
Push("Underline")2Top ← 3; ActionStack[3] ← "Underline"31:Bold, 2:Italic, 3:Underline
LastAction ← Pop()3Removed ← ActionStack[3] = “Underline”; Top ← 221:Bold, 2:Italic
Push("ResizeFont")2Top ← 3; ActionStack[3] ← "ResizeFont" (overwrites the old, already-removed “Underline”)31:Bold, 2:Italic, 3:ResizeFont
NextAction ← Pop()3Removed ← ActionStack[3] = “ResizeFont”; Top ← 221:Bold, 2:Italic

So LastAction = "Underline" and NextAction = "ResizeFont".

[4 marks]: [2] for correctly tracing Top through all six calls, [1] for the correct value of LastAction, [1] for the correct value of NextAction.

Part (b): Tracing the queue (enqueue and dequeue)

A queue is First-In-First-Out (FIFO): Enqueue adds an item at the position after Rear, and Dequeue removes the item at Front, always leaving items already enqueued but not yet printed in their original order.

CallFront, Rear beforeWhat happensFront, Rear after
Enqueue("Report.docx")0, 0Rear ← 1; PrintQueue[1] ← "Report.docx"; Front was 0 so Front ← 11, 1
Enqueue("Invoice.pdf")1, 1Rear ← 2; PrintQueue[2] ← "Invoice.pdf"1, 2
Enqueue("Timetable.xlsx")1, 2Rear ← 3; PrintQueue[3] ← "Timetable.xlsx"1, 3
FirstPrinted ← Dequeue()1, 3Removed ← PrintQueue[1] = “Report.docx”; Front ← 22, 3
Enqueue("Poster.png")2, 3Rear ← 4; PrintQueue[4] ← "Poster.png"2, 4
SecondPrinted ← Dequeue()2, 4Removed ← PrintQueue[2] = “Invoice.pdf”; Front ← 33, 4

So FirstPrinted = "Report.docx" and SecondPrinted = "Invoice.pdf". The remaining documents (“Timetable.xlsx” at index 3 and “Poster.png” at index 4) stay in the order they were sent.

[4 marks]: [2] for correctly tracing Front and Rear through all six calls, [1] for the correct value of FirstPrinted, [1] for the correct value of SecondPrinted.

Final answers

  • (a) Top: 1, 2, 3, 2, 3, 2. LastAction = "Underline", NextAction = "ResizeFont".
  • (b) (Front, Rear): (1,1), (1,2), (1,3), (2,3), (2,4), (3,4). FirstPrinted = "Report.docx", SecondPrinted = "Invoice.pdf".