Queue (ADT)

Context: FIT1008_MOC · a FIFO Abstract Data Type (ADT) · backbone clustering its LinearQueue / CircularQueue / LinkQueue implementations · the dual of Stack (ADT)

Quick Revision

  • 🎯 Objective: FIFO front-only access ➔ the ADT behind BFS, scheduling, buffering, producer–consumer.
  • 📦 Core Components: Contractappend/serve, two moving ends | LinearQueue ➔ leaks space | CircularQueue ➔ ring, no waste | LinkQueue ➔ two-pointer chain, unbounded.
  • ⚡ Key Constraint: all ops two ends move ⟹ array versions need front+rear, creating the wasted-space flaw the ring fixes.

📝 Core

1. Queue Contract (FIFO)

  • FIFO disciplineappend at rear, serve from front; only the front accessible.
  • Interfaceappend · serve · is_empty · is_full · __len__ · clear.
  • Stack contrast ➔ single difference = access end (LIFO newest vs FIFO oldest) ➔ queues for arrival-order (BFS, scheduling).

2. LinearQueue (Naïve Array)

  • Storage substrate ➔ fixed Array (Data Structure) + front, rear, length; both indices move rightward only.
  • Invariant ➔ valid data front..rear-1, rear - front == length (Invariant).
  • Space leakis_full tests rear == len(array) ➔ reports full while holding freed cells.

3. CircularQueue (Ring Buffer)

  • Mechanism ➔ array as a ring; front/rear wrap to 0 via modulo ➔ reuses freed cells, all .
  • Full/empty ambiguity ➔ both give rear == front ➔ track length OR sacrifice one slot.
  • Traversal ➔ must start at front and step % len (live cells may straddle the end).

4. LinkQueue (Two-Pointer Chain)

  • Storage substrateNode chain + front (serve) and rear (append) pointers.
  • rear payoff ➔ tail-append (vs for a plain LinkList); unbounded, no wrap logic.
  • Invariantfront is Nonerear is None; the two empty-boundary transitions must keep both in sync.

⚙️ Core Implementation

🔹 Abstract Base — the contract

🔹 LinearQueue — the wasted-space flaw

🔹 CircularQueue — the ring

🔹 LinkQueue — two pointers

⚖️ Core Decision Matrix

Variant / StrategyTrigger ConditionAdvantage (Pro)Disadvantage (Con) / Complexity BoundCache / Memory Impact
LinearQueuePedagogical onlysimple opsleaks served cells, false-fullcontiguous
CircularQueueBounded, perf-critical, full array usablefixed capacitycontiguous, cache-friendly
LinkQueueVariable / unbounded, never full pointer/nodescattered, poor locality

When It Flips: circular = linear's without the space leak (used in network rings, audio buffers, OS run-queues); choose linked only when size is genuinely unbounded — doubly-link for an deque, Michael–Scott CAS for lock-free concurrency.

📊 Exam Execution Trace

Manual Execution Trace

CircularQueue(cap 4): append A,B,C; serve; append D,E

Step / StateTrigger Oparray (cap 4)frontrearlenReturn Payload
0 (Init)init[_,_,_,_]000
1append A[A,_,_,_]011
2append B[A,B,_,_]022
3append C[A,B,C,_]033
4serve[A,B,C,_]132A
5append D[A,B,C,D]103
6append E[E,B,C,D]114

rear wraps ; queue is full (len == 4) with live order B,C,D,E.

Applied Exercise

Problem: Show why rear == front cannot detect fullness in a ring. Derivation Proof / Hand-Calculation Walkthrough:

Final Extracted Output: fullness requires a length counter (or the sacrifice-a-slot trick), not a position test.

🧠 Active Recall