zoukankan      html  css  js  c++  java
  • 剑指offer——stack与queue的互相实现

    我们知道,stack和queue是C++中常见的container。下面,我们来探究下如何以stack来实现queue,以及如何用queue来实现stack。

    首先,先了解下stack与queue的基本属性。

    一、stack

      1,参数要求

         stack模板类需要两个参数:一个元素类型,一个容器类型。容器类型缺省为deque。

      2,基本操作

        入栈:s.push(element);element加入栈顶。

        出栈:s.pop(),栈顶元素被删除,无返回值。

        访问栈顶:s.top()。取得栈顶元素。

        判断栈空:s.empty()。栈空,返回true;非空,返回false。

        长度判断:s.size()。返回栈张元素个数

    二、queue

      1,参数要求

        queue模板类需要两个参数:一个元素类型,一个容器类型。容器类型缺省为deque。

      2,基本操作

        入队:q.push(element)。element加入到队列的末端。

        出对:q.pop()。弹出(删除)队列的第一个元素(q.front())。无返回值。

        访问队首:q.front(), 即最早被压入队列的元素。

        访问队尾:q.back(),即最后被压入队列的元素。

        判断队空:q.empty()。队空,返回true。

        长度判断:q.size()。返回队列中元素个数。

    三、两个stack实现queue

      在基本了解了stack和queue这两个container后,我们来看看如何用stack实现queue。

      如上所诉,queue包含了push(), pop(),front(),back(),empty()这些基本操作,现在的问题 就是如何用stack实现这些操作。

      1,分析(已知stack A 和stack B)

       入队:将元素进栈A

       出队:判断B是否为空,如果为空,则将栈A中所有元素pop, 并push进 栈B,栈B出栈。

       访问队首:栈B的栈顶。

       访问队尾:如果栈A非空,队尾即栈A的栈顶(A.top());如果栈A为空,队尾为栈B的栈底(怎么取得栈B的栈底?利用第三个stack??

       队空:两个栈空,则队空。

       长度:A.size(),  B.size()

      2,示意代码(未实现back())

     1 class Stack2queue {
     2 public:
     3     void push(int node) {
     4         stack1.push(node);
     5     }
     6 
     7     void pop() {
     8         if (stack2.empty()) {
     9             if (stack1.empty())
    10                 throw runtime_error("No elements");
    11             else {
    12                 while (!stack1.empty()) {
    13                     stack2.push(stack1.top());
    14                     stack1.pop();
    15                 }
    16                 stack2.pop();
    17             }
    18 
    19         }else
    20             stack2.pop();
    21     }
    22     int front() {
    23         if (stack2.empty()) {
    24             if (stack1.empty())
    25                 throw runtime_error("No elements");
    26             else {
    27                 while (!stack1.empty()) {
    28                     stack2.push(stack1.top());
    29                     stack1.pop();
    30                 }
    31                 return stack2.top();
    32             }
    33 
    34         }else
    35             return stack2.top();
    36     }
    37 
    38     bool myEmpty() {
    39         if (stack1.empty() && stack2.empty())
    40             return true;
    41         else
    42             return false;
    43     }
    44 private:
    45     stack<int> stack1;
    46     stack<int> stack2;
    47 };
    View Code

        示意代码中未实现back()操作,笔者的想法是:若栈A为空,将stack B的元素pop出来,再push进 stack C。C的栈顶元素即是队尾。但是这样就新增了一个stack。不知道给广大博友是否有更好的方法?

    四、两个queue实现stack

      1,分析(queue A 和 queue B)

         入栈:将元素push进队列A

         出栈:判断队列A是否为空。空,则把队列B的元素出队列,进队列A,A再出队列进队列B,直到A中元素剩1,然后A.pop();非空,队列A中元素出队列进队列B,直到A中元素剩1,然后A.pop().

        访问栈顶:与出栈类似,只不过由A.pop()B变为了A.front()或A.back(), 因为此时A只剩下一个元素。

        判断栈空:queue1.empty() && queue2.empty()

        长度:queue1.size() + queue2.size()

      2,示意代码

     1 class Queue2stack {
     2 public:
     3     void push(int);
     4     void pop();
     5     int top();
     6     bool myempty();
     7 private:
     8     queue<int> queue1;
     9     queue<int> queue2;
    10 };
    11 void Queue2stack::push(int element) {
    12     queue1.push(element);
    13 }
    14 
    15 void Queue2stack::pop() {
    16     if(!queue1.empty()) {
    17         while(queue1.size() > 1) {
    18             queue2.push(queue1.front());
    19             queue1.pop();
    20         }
    21         queue1.pop();
    22 
    23     }
    24     else {
    25         if(!queue2.empty()) {
    26             while (!queue2.empty()) {
    27                 queue1.push(queue2.front());
    28                 queue2.pop();
    29             }
    30             while(queue1.size() > 1) {
    31                 queue2.push(queue1.front());
    32                 queue1.pop();
    33             }
    34             queue1.pop();
    35         }
    36 
    37     }
    38 }
    39 
    40 int Queue2stack::top() {
    41     if(!queue1.empty()) {
    42         while(queue1.size() > 1) {
    43             queue2.push(queue1.front());
    44             queue1.pop();
    45         }
    46         return queue1.back();
    47 
    48     }
    49     else {
    50         if(!queue2.empty()) {
    51             while (!queue2.empty()) {
    52                 queue1.push(queue2.front());
    53                 queue2.pop();
    54             }
    55             while(queue1.size() > 1) {
    56                 queue2.push(queue1.front());
    57                 queue1.pop();
    58             }
    59             return queue1.back();
    60         }
    61     }
    62     throw runtime_error("No elements!");
    63 
    64 }
    65 
    66 bool Queue2stack::myempty() {
    67     if(queue1.empty() && queue2.empty())
    68         return true;
    69     else
    70         return false;
    71 }
    View Code

    五、综合测试

      上述讨论,介绍了stack和queue的相互实现。下面这个例子来检测我们的算法是否正确。

      1 #include <iostream>
      2 #include <stack>
      3 #include <queue>
      4 using namespace std;
      5 
      6 class Stack2queue {
      7 public:
      8     void push(int node) {
      9         stack1.push(node);
     10     }
     11 
     12     void pop() {
     13         if (stack2.empty()) {
     14             if (stack1.empty())
     15                 throw runtime_error("No elements");
     16             else {
     17                 while (!stack1.empty()) {
     18                     stack2.push(stack1.top());
     19                     stack1.pop();
     20                 }
     21                 stack2.pop();
     22             }
     23 
     24         }else
     25             stack2.pop();
     26     }
     27     int front() {
     28         if (stack2.empty()) {
     29             if (stack1.empty())
     30                 throw runtime_error("No elements");
     31             else {
     32                 while (!stack1.empty()) {
     33                     stack2.push(stack1.top());
     34                     stack1.pop();
     35                 }
     36                 return stack2.top();
     37             }
     38 
     39         }else
     40             return stack2.top();
     41     }
     42 
     43     bool myEmpty() {
     44         if (stack1.empty() && stack2.empty())
     45             return true;
     46         else
     47             return false;
     48     }
     49 private:
     50     stack<int> stack1;
     51     stack<int> stack2;
     52 };
     53 
     54 class Queue2stack {
     55 public:
     56     void push(int);
     57     void pop();
     58     int top();
     59     bool myempty();
     60 private:
     61     queue<int> queue1;
     62     queue<int> queue2;
     63 };
     64 void Queue2stack::push(int element) {
     65     queue1.push(element);
     66 }
     67 
     68 void Queue2stack::pop() {
     69     if(!queue1.empty()) {
     70         while(queue1.size() > 1) {
     71             queue2.push(queue1.front());
     72             queue1.pop();
     73         }
     74         queue1.pop();
     75 
     76     }
     77     else {
     78         if(!queue2.empty()) {
     79             while (!queue2.empty()) {
     80                 queue1.push(queue2.front());
     81                 queue2.pop();
     82             }
     83             while(queue1.size() > 1) {
     84                 queue2.push(queue1.front());
     85                 queue1.pop();
     86             }
     87             queue1.pop();
     88         }
     89 
     90     }
     91 }
     92 
     93 int Queue2stack::top() {
     94     if(!queue1.empty()) {
     95         while(queue1.size() > 1) {
     96             queue2.push(queue1.front());
     97             queue1.pop();
     98         }
     99         return queue1.back();
    100 
    101     }
    102     else {
    103         if(!queue2.empty()) {
    104             while (!queue2.empty()) {
    105                 queue1.push(queue2.front());
    106                 queue2.pop();
    107             }
    108             while(queue1.size() > 1) {
    109                 queue2.push(queue1.front());
    110                 queue1.pop();
    111             }
    112             return queue1.back();
    113         }
    114     }
    115     throw runtime_error("No elements!");
    116 
    117 }
    118 
    119 bool Queue2stack::myempty() {
    120     if(queue1.empty() && queue2.empty())
    121         return true;
    122     else
    123         return false;
    124 }
    125 int main()
    126 {
    127     // stack to queue
    128     Stack2queue s2q;
    129     for (int i = 1; i < 10; ++i) {
    130         s2q.push(i);
    131     }
    132     while (!s2q.myEmpty()) {
    133         cout << s2q.front() << ' ';
    134         s2q.pop();
    135     }
    136 
    137     //queue to stack
    138     cout << endl;
    139     Queue2stack q2s;
    140     for (int i = 1; i < 10; ++i) {
    141         q2s.push(i);
    142     }
    143     while(!q2s.myempty()) {
    144         cout << q2s.top() << ' ';
    145         q2s.pop();
    146     }
    147     //system("pause");
    148     return 0;
    149 }
    View Code

      实验结果:

      

      我们看到,我们很好的用stack模拟了queue,达到了先进先出的效果;同样,我们也很好的用queue模拟了stack,先进后出的效果。

      不过,值得考虑的是,笔者在用stack实现queue时,没有实现back()操作。各位博友有啥好想法呢?

  • 相关阅读:
    洛谷P3796
    cf1291c-Mind Control
    莫比乌斯函数
    C. Mixing Water(三分)
    E. Modular Stability(思维构造)
    【美团杯2020】平行四边形
    原根定义
    E. Are You Fired?(思维)
    102606C. Coronavirus Battle time limit per test4 seconds(三维拓扑序)
    E
  • 原文地址:https://www.cnblogs.com/letgo/p/5733430.html
Copyright © 2011-2022 走看看