How to implement queue with stack?

Interesting topic, right? One of my friends encounter this problem when he’s applying software engineer position in a company.

Suppose we have only stack available

Stack* stack_init();
void push(Stack*, int);
int pop(Stack*);
void stack_free();

Please implement the following interface of queue

Queue* queue_init();
void inq(Queue*, int);
int outq(Queue*);
void queue_free();

Any idea, buddy? Here come 3 solutions:

1) By Winters Mi

  1. Stack* stack_init();
  2. void push(Stack*, int);
  3. int pop(Stack*);
  4. void stack_free(Stack*);
  5.  
  6. struct Queue {
  7.     struct Stack* stack_;
  8. }
  9.  
  10. Queue* queue_init()
  11. {
  12.     Queue* queue = new Queue;
  13.     queue->stack_ = stack_init();
  14. }
  15.  
  16. void inque(Queue* que, int newvalue)
  17. {
  18.     Stack* temp = stack_init();
  19.     int value;
  20.     while((value = pop(que->stack_) != EOF){
  21.     push(temp, value);
  22. }
  23. push(que->stack_, newvalue);
  24.     while((value = pop(temp)) != EOF){
  25.         push(que->stack_, value);
  26.     }
  27. }
  28.  
  29. int outque(Queue* que)
  30. {
  31.     pop(que->stack_);
  32. }
  33.  
  34. void queue_free(Queue* que)
  35. {
  36.     stack_free(que->stack_);
  37.     delete que;
  38. }

So, it’s a O(N) solution.

2) By Green Wang

  1. struct Queue
  2. {
  3.     struct Stack *stack_forward;
  4.     struct Stack *stack_backward;
  5.     int iStack;
  6. }
  7.  
  8. Queue* queue_init()
  9. {
  10.     Queue* que = new Queue;
  11.     que->stack_forward = stack_init();
  12.     que->stack_backward = stack_init();
  13.     que->iStack = 1;
  14.    
  15.     return que;
  16. }
  17.  
  18. void stack_reverse(Stack *dest, Stack *src)
  19. {
  20.     int value;
  21.     while((value = pop(src) != EOF)
  22.     {
  23.         push(dest, value);
  24.     }
  25. }
  26.  
  27. void inque(Queue *que, int newvalue)
  28. {
  29.     if (que->iStack != 1)
  30.     {
  31.         stack_reverse(que->stack_forward, que->stack_backward);
  32.         que->iStack = 1;
  33.     }
  34.    
  35.     push(que->stack_forward, newvalue);
  36. }
  37.  
  38. int outque(Queue *que)
  39. {
  40.     if (que->iStack != -1)
  41.     {
  42.         stack_reverse(que->stack_backward, que->stack_forward);
  43.         que->iStack = -1;
  44.     }
  45.    
  46.     return pop(que->stack_backward)
  47. }
  48.  
  49. void queue_free(Queue* que)
  50. {
  51.     stack_free(que->stack_forward);
  52.     stack_free(que->stack_backward);
  53.     delete que;
  54. }

If the operation of the queue is consecutive "in" or "out", it’s O(1); Or else O(n). This algorithm overcomes the shortcoming of the first one. Because if the operation is consecutive, we don’t need to reverse the stack back.

3) By Changzheng Liu

  1. /* create the type Queue by Stack */
  2. typedef struct {
  3.     Stack* stack_out;
  4.     Stack* stack_in;
  5. } Queue;
  6.  
  7. /* Init Queue */
  8. Queue* queue_init()
  9. {
  10.     Queue* que = (Queue*)malloc(sizeof(Queue));
  11.     que->stack_out = stack_init();
  12.     que->stack_in = stack_init();
  13.     return que;
  14. }
  15.  
  16. /* reverse the elements from src to dest */
  17. void stack_reverse(Stack *dest, Stack *src)
  18. {
  19.     int value;
  20.     while((value = pop(src) != EOF)
  21.     {
  22.         push(dest, value);
  23.     }
  24. }
  25.  
  26. /* put element into queue */
  27. void inque(Queue* que, int elem)
  28. {
  29.     /* always push elements into stack_in */
  30.     push(que->stack_in, elem);
  31. }
  32.  
  33. /* get the element from queue */ 
  34. int outque(Queue* que)
  35. {
  36.     int ret;
  37.    
  38.     /* always get element from stack_out,
  39.     * if stack_out is empty, reverse stack_in to stack_out and try to pop from stack_out again
  40.     */
  41.     if ((ret = pop(que->stack_out)) == EOF)
  42.     {
  43.         stack_reverse(que->stack_out, que->stack_in);
  44.         ret = pop(que->stack_out);
  45.     }
  46.  
  47.     return ret;
  48. }
  49.  
  50. /* free the queue */
  51. void queue_free(Queue* que)
  52. {
  53.     stack_free(que->stack_out);
  54.     stack_free(que->stack_in);
  55.     free(que);
  56. }

Changzheng got these code from Google. :P. It’s really good. The idea is very simple, 2 stacks, one for in and one for out. For the "in" operation, just push all into the stack_in. For the "out" operation, if stack_out is empty, reverse the stack_in to stack_out, or else just pop the value.

So for "in" operation O(1); for "out" operation, if stack_out is empty, it’s O(n), else O(1).

Popularity: 28%

Related entries:

  • No Related Posts

One Response to “How to implement queue with stack?”

  1. How To Start A Blog Says:

    How To Start A Blog…

    I couldn’t understand some parts of this article, but it sounds interesting…

Leave a comment

(required)

(required)


Information for comment users
Line and paragraph breaks are implemented automatically. Your e-mail address is never displayed. Please consider what you're posting.

Use the buttons below to customise your comment.


RSS feed for comments on this post | TrackBack URI

 

Creative Commons License
This work is licensed under a Creative Commons License.

没有什么能够阻挡,你对未来的向往