{"id":684,"date":"2009-02-09T16:56:07","date_gmt":"2009-02-10T00:56:07","guid":{"rendered":"http:\/\/www.curlybrace.com\/words\/?p=684"},"modified":"2010-08-06T12:12:12","modified_gmt":"2010-08-06T19:12:12","slug":"queue-implemented-using-stack","status":"publish","type":"post","link":"https:\/\/www.curlybrace.com\/words\/2009\/02\/queue-implemented-using-stack\/","title":{"rendered":"Queue Implemented Using Stacks"},"content":{"rendered":"<p>Here are two solutions for using stacks to emulate a queue.  The first always keeps one or both stacks empty, shifts the set of values back and forth as the caller switches between enqueuing and dequeueing.  The second maintains an input stack and an output stack.  All enqueued data goes directly onto the input stack.  When dequeue is called, if the output stack has anything on it, it takes the topmost value, otherwise it transfers the entire input stack into the output stack.<\/p>\n<p>The latter implementation is more efficient &#8212; transfer between the two stacks occurs only when dequeue is called <b>and<\/b> the output stack is already empty &#8212; as well as more compact and readable.<\/p>\n<h3>Stack-Swapping Implementation<\/h3>\n<p>This version keeps one stack empty, and swaps all content between the two each time we switch between enqueue and dequeue operations.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stack&gt;\r\n\r\n\/\/ This implementation uses two stacks.  It keeps one empty, and swaps content\r\n\/\/ whenever we switch between eprforming enqueues and dequeues.\r\nclass FakeQueue\r\n{\r\n    std::stack&lt;int&gt; s1;\r\n    std::stack&lt;int&gt; s2;\r\n\r\n\t\/\/ We need to keep track of the last operation (push vs. pop) so that we can\r\n    \/\/ resorder our stack whenever we switch between enqueue and dequeue.\r\n\ttypedef enum { PUSH = 0, POP } STACK_OPS;\r\n\tSTACK_OPS last_op;\r\n\r\n\tvoid SwapStacks();\r\n\r\npublic:\r\n\tvoid enqueue(int i);\r\n\tbool dequeue(int &amp;i);\r\n\r\n\tFakeQueue() : last_op(PUSH)\r\n\t{ \/* empty constructor *\/ }\r\n};\r\n\r\n\/\/ SwapStacks swaps the stack between s1 and s2.\r\nvoid FakeQueue::SwapStacks()\r\n{\r\n\tif (s1.empty())\r\n\t{\r\n\t\twhile (!s2.empty())\r\n\t\t{\r\n\t\t\ts1.push(s2.top());\r\n\t\t\ts2.pop();\r\n   \t\t}\r\n\t}\r\n\telse\r\n\t{\r\n        while (!s1.empty())\r\n        {\r\n            s2.push(s1.top());\r\n            s1.pop();\r\n        }\r\n    }\r\n}\r\n\r\nvoid FakeQueue::enqueue(int i)\r\n{\r\n\tif (last_op == POP)\r\n\t{\r\n\t\tSwapStacks();\r\n\t\tlast_op = PUSH;\r\n\t}\r\n\r\n\tif (s1.empty())\r\n        s2.push(i);\r\n\telse\r\n        s1.push(i);\r\n}\r\n\r\n\/\/ Retrieves the oldest item in the virtual queue.  If the queue is empty, sets i to\r\n\/\/ -1 and returns false.  Otherwise, it returns true.\r\nbool FakeQueue::dequeue(int &amp;i)\r\n{\r\n    if (last_op == PUSH)\r\n    {\r\n        SwapStacks();\r\n        last_op = POP;\r\n    }\r\n\r\n    if (!s1.empty())\r\n    {\r\n        i = s1.top();\r\n        s1.pop();\r\n        return true;\r\n    }\r\n    else if (!s2.empty())\r\n    {\r\n        i = s2.top();\r\n        s2.pop();\r\n        return true;\r\n    }\r\n    else\r\n    {\r\n        \/\/ Queue is empty.\r\n        i = -1;\r\n        return false;\r\n    }\r\n}\r\n\r\nint main(int \/*argc*\/, char ** \/*argv*\/)\r\n{\r\n    FakeQueue queue;\r\n    int i;\r\n\r\n    \/\/ Perform a variety of queues and dequeues to show that the queue order is\r\n    \/\/ always maintained.\r\n\r\n    queue.enqueue(1);\r\n    queue.enqueue(2); \/\/ contains { 1, 2 }\r\n\r\n    queue.dequeue(i);\r\n    printf(&quot;Dequeued %d\\n&quot;, i);\r\n\r\n    queue.enqueue(3);\r\n    queue.enqueue(4); \/\/ contains { 2, 3, 4 }\r\n\r\n    queue.dequeue(i);\r\n    printf(&quot;Dequeued %d\\n&quot;, i);\r\n\r\n    queue.enqueue(5); \/\/ contains { 3, 4, 5 }\r\n\r\n    while (queue.dequeue(i))\r\n    {\r\n        printf(&quot;Dequeued %d\\n&quot;, i);\r\n    }\r\n\r\n    return 0;\r\n}\r\n<\/pre>\n<h3>Input-Output Stack Implementation<\/h3>\n<p>This version uses dedicated input and output stacks.  All input goes on the input stack.  When dequeue is called, if the output stack has anything on it, it takes the topmost value, otherwise it transfers the entire input stack into the output stack.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stack&gt;\r\n\r\n\/\/ The second implementation uses dedicated input and output stacks.\r\nclass FakeQueue\r\n{\r\n    std::stack&lt;int&gt; in;\r\n    std::stack&lt;int&gt; out;\r\n\r\npublic:\r\n    void enqueue(int i);\r\n    bool dequeue(int &amp;i);\r\n};\r\n\r\nvoid FakeQueue::enqueue(int i)\r\n{\r\n    in.push(i);\r\n}\r\n\r\nbool FakeQueue::dequeue(int &amp;i)\r\n{\r\n    \/\/ Abort if our queue is empty.\r\n    if (in.empty() &amp;&amp; out.empty())\r\n    {\r\n        i = -1;\r\n        return false;\r\n    }\r\n\r\n    \/\/ If the &quot;out&quot; stack is empty, shift the contents of the &quot;in&quot; stack into\r\n    \/\/ it...\r\n    if (out.empty())\r\n    {\r\n        while (!in.empty())\r\n        {\r\n            out.push(in.top());\r\n            in.pop();\r\n        }\r\n    }\r\n\r\n    \/\/ Pop the return value from the &quot;out&quot; stack:\r\n    i = out.top();\r\n    out.pop();\r\n\r\n    return true;\r\n}\r\n\r\nint main(int \/*argc*\/, char ** \/*argv*\/)\r\n{\r\n    FakeQueue queue;\r\n    int i;\r\n\r\n    \/\/ Perform a variety of queues and dequeues to show that the queue order is\r\n    \/\/ always maintained.\r\n\r\n    queue.enqueue(1);\r\n    queue.enqueue(2); \/\/ contains { 1, 2 }\r\n\r\n    queue.dequeue(i);\r\n    printf(&quot;Dequeued %d\\n&quot;, i);\r\n\r\n    queue.enqueue(3);\r\n    queue.enqueue(4); \/\/ contains { 2, 3, 4 }\r\n\r\n    queue.dequeue(i);\r\n    printf(&quot;Dequeued %d\\n&quot;, i);\r\n\r\n    queue.enqueue(5); \/\/ contains { 3, 4, 5 }\r\n\r\n    while (queue.dequeue(i))\r\n    {\r\n        printf(&quot;Dequeued %d\\n&quot;, i);\r\n    }\r\n\r\n    return 0;\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Here are two solutions for using stacks to emulate a queue. The first always keeps one or both stacks empty, shifts the set of values back and forth as the caller switches between enqueuing and dequeueing. The second maintains an &hellip; <a href=\"https:\/\/www.curlybrace.com\/words\/2009\/02\/queue-implemented-using-stack\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[262,261],"tags":[263],"class_list":["post-684","post","type-post","status-publish","format-standard","hentry","category-algorithms","category-cplusplus","tag-interview-question"],"_links":{"self":[{"href":"https:\/\/www.curlybrace.com\/words\/wp-json\/wp\/v2\/posts\/684","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.curlybrace.com\/words\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.curlybrace.com\/words\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.curlybrace.com\/words\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.curlybrace.com\/words\/wp-json\/wp\/v2\/comments?post=684"}],"version-history":[{"count":15,"href":"https:\/\/www.curlybrace.com\/words\/wp-json\/wp\/v2\/posts\/684\/revisions"}],"predecessor-version":[{"id":1225,"href":"https:\/\/www.curlybrace.com\/words\/wp-json\/wp\/v2\/posts\/684\/revisions\/1225"}],"wp:attachment":[{"href":"https:\/\/www.curlybrace.com\/words\/wp-json\/wp\/v2\/media?parent=684"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.curlybrace.com\/words\/wp-json\/wp\/v2\/categories?post=684"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.curlybrace.com\/words\/wp-json\/wp\/v2\/tags?post=684"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}