Implement queue behavior with an input stack and an output stack.

Algorithm

The replay uses the same three values in every language, so this Perl DSA implementation can be compared directly with the rest of the DSA track.

input stack Enqueue pushes new values onto the input stack.
output stack When the output stack is empty, transferring all input values reverses them into dequeue order.

Visual walkthrough

The two-stack queue keeps cheap enqueues in the input stack, then reverses that stack only when dequeue needs the output stack.

Step 1 - Enqueue pushes onto the input stack

After enqueueing 10, 20, 30, the newest input value is on top of the input stack.

After enqueues: input top is 30; output is empty.input stack top -> bottomoutput stack top -> bottomremoved30(empty)(empty)2010

Step 2 - Transfer reverses into output order

Moving every input value to the output stack turns 10 into the next pop.

After transfer: output top is 10, so dequeue returns the oldest value.input stackoutput stack top -> bottomremoved(empty)10(empty)2030

Step 3 - Dequeue pops from output

The output stack pops 10 first while 20 becomes the next front.

After one dequeue: removed is 10; output top is now 20.input stackoutput stack top -> bottomremoved(empty)201030

Basic Implementation

basic.pl
use strict;
use warnings;

sub render { return join(" -> ", @_); }

my @in_stack;
my @out_stack;
push @in_stack, $_ for (10, 20, 30);
push @out_stack, pop @in_stack while @in_stack;
my @removed;
push @removed, pop @out_stack while @out_stack;
print render(@removed), "\n";

Complexity

  • Time: O(1) amortized per operation
  • Space: O(n)

Implementation notes

  • my @in_stack and my @out_stack are the two Perl arrays used as stacks; both use the @ sigil.
  • The replay starts with both stacks empty: input [], output [].
  • Enqueue uses push @in_stack, $_ for (10, 20, 30), appending each value to the top of the input stack.
  • After enqueue, the input stack is [10, 20, 30] and the output stack is still [].
  • Transfer uses push @out_stack, pop @in_stack while @in_stack.
  • In that while @in_stack condition, @in_stack is in scalar context, so it means "while the stack has length".
  • pop @in_stack removes from the end: 30, then 20, then 10.
  • push @out_stack, ... appends those popped values, giving output stack [30, 20, 10] and emptying the input stack.
  • Dequeue then uses push @removed, pop @out_stack while @out_stack.
  • Popping the output stack returns 10, then 20, then 30, which restores FIFO order.
  • The trace ends with removed values [10, 20, 30] and output stack [].
  • render(@removed) joins the removed values with " -> ", and print render(@removed), "\n" outputs 10 -> 20 -> 30.