简体   繁体   中英

How to Implement a Queue With Two Stacks

Today I had a data structures exam. One of the questions was how to implement queue functions which are enqueue and dequeue given stacks s1 and s2 . I have used this method, is this correct?

enqueue(& item)
   if(!s2.isEmpty())
      s1.push(s2.pop());
   s1.push(item);
dequeue
   if(!s1.isEmpty())
      s2.push(s1.pop());
   return s2.pop();

Typically if you have a stack like this:

[1,2,3,4]

The problem here is that popping will want to pop in a LIFO order, meaning it would want to pop element 4 . A queue should pop in FIFO order and pop element 1 .

To get this kind of behavior, we basically need to be able to pop in reverse order. A second stack can allow us to actually reverse the contents of a stack. Imagine looping through the stack above and popping from it and pushing the contents to another stack:

[1,2,3,4] []
[1,2,3]   [4]
[1,2]     [4,3]
[1]       [4,3,2]
[]        [4,3,2,1]

Now when we pop from the second stack, we pop 1 as desired.

But to do this in proper order, we have to first loop through all the elements of the first stack and transfer them to the second. So there should actually be loops in your enqueue/dequeue operation to flip (reverse) the contents of these stacks.

That's where the second stack comes in handy: it lets you reverse the contents of a stack through a transfer. But you're going to need a loop for that, since imagine enqueuing 4 elements. Now to dequeue, you need a loop to reverse the contents. You could treat s1 as the pushing stack and s2 as the popping stack. It seems you had the right idea but we need a slight tweak:

enqueue(item):
   while(!s2.isEmpty())
      s1.push(s2.pop());
   s1.push(item);

dequeue(item):
   while(!s1.isEmpty())
      s2.push(s1.pop());
   return s2.pop();

For what it's worth, the enqueue doesn't need a loop. If you have two stacks, enqueueStack and dequeueStack, you just need to push onto enqueueStack and reverse onto dequeueStack whenever it's empty.

enqueue(item):
    enqueueStack.push(item);
dequeue(item):
    if(dequeueStack.isEmpty()){
        while(!enqueueStack.isEmpty()){
            dequeueStack.push(enqueueStack.pop());
        }
    }
    return dequeueStack.pop()

Saves a little time if the stacks get large.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM