使用两个队列实现一个栈,使用两个栈实现一个队列!

转自:http://blog.csdn.net/zgh1988/article/details/6988904

时间:小师妹请客之后,2013/6/16

1、这里所说的都是STL中的queue,stack

     其中queue的特点是先进先出,它所具有的函数有:

     queue<int>

     void push(int elem)                              //向队列中添加元素

     void pop()                                              //从队列中删除头元素,即先进入的先出去

     int front();                                               //返回队列中的头元素,即队列中最先进入的元素

     int back();                                               //返回队列中的末尾元素,即队列中的最后进入的元素

      int size() const;                                    //返回队列中元素的个数

     bool empty() const ;                            // 判断队列是否为空,空返回true,非空返回false。

    其中stack 的特点是后进先出,它所具有的函数有:

   stack<int>

    void push(int elem);                             // 向栈中添加一个元素

    void pop();                                              //删除栈中的一个元素,即最后进入的元素

    int top() const;                                       // 返回栈中的头元素,即最后进入的元素。

    int size() const;                                     // 返回栈中元素的个数

    bool empty() const;                             // 判断栈是否为空,空返回true,非空返回false;

2、如何使用两个队列实现一个栈

         (1)  使用两个队列 q1, q2, 还有两个bool变量 q1_used, q2_used,分别表示q1是否在使用,q2是否在使用,两者只有一个在使用,另一个不在使用。初始状态为 q1_used = true;  q2_used = false;即此时q1在使用,q2闲置。

          (2) 实现栈的push操作,首先判断q1_used,q2_used,然后找出正在使用队列,将其添加到队列中。例如q1_used == true;  则将元素添加到队列q1;  反之q2_used == true,则将元素添加到队列q2中。

           (3)  实现栈的pop操作,首先判断q1_used ,q2_used,找出正在使用的队列,然后将在使用的队列元素取出来,放到闲置的队列中,删除队列最后一个元素。然后修改q1_used, q2_used.

              例如初始状态为q1_used = true,a,b,c入栈,则将其插入队列q1中,然后执行出栈操作pop,则将a,b从q1中出队列,然后进入q2,将c进行pop操作。

                       

                  (4)执行top操作,判断q1_used q2_used,然后找出正在使用的队列,利用该队列函数back(),返回栈头元素值。

                   (5) 至于size()和empty()操作,就对正在使用的队列,执行size()和empty()函数,返回值。

 

下面为实现代码:

                     

#ifndef STACK_H
#define STACK_H

#include <queue>
#include <iostream>

template <typename T>
class Stack {
private:
 std::queue<T> q1;
 std::queue<T> q2;
 bool q1_used, q2_used;
public:
 Stack();
 void push(T elem);
 void pop();
 T top() const;
 bool empty() const;
 int size() const;
};

template <typename T>
Stack<T>::Stack() {
 q1_used = true;
 q2_used = false;
}

template <typename T>
void Stack<T>::push(T elem) {
 if(q1_used == true) {
  q1.push(elem);
 }
 if(q2_used == true) {
  q2.push(elem);
 }
}

template <typename T>
void Stack<T>::pop() {
 if(!q1.empty() && q1_used == true) {
  while(q1.size() != 1) {
   q2.push(q1.front());
   q1.pop();
  }
  q1.pop();
  q2_used = true;
  q1_used = false;
  return;
 }
 if(!q2.empty() && q2_used == true) {
  while(q2.size() != 1) {
   q1.push(q2.front());
   q2.pop();
  }
  q2.pop();
  q2_used = false;
  q1_used = true;
  return;
 }
 std::cout << "error! Stack::pop()" << std::endl;
}

template <typename T>
T Stack<T>::top() const {
 if(!q1.empty() && q1_used == true) {
  return q1.back();
 }
 else if(!q2.empty() && q2_used == true) {
  return q2.back();
 }
 std::cout << "error! Stack::top()" << std::endl;
 return 0;
}

template <typename T>
bool Stack<T>::empty() const {
 return q1.empty() && q1_used == true || q2.empty() && q2_used == true;
}

template <typename T>
int Stack<T>::size() const {
 if(!q1.empty() && q1_used == true) {
  return q1.size();
 }
 if(!q2.empty() && q2_used == true) {
  return q2.size();
 }
 return 0;
}

#endif

测试程序为:

#include "Stack.h"

int main() {
 Stack<int> s1;
 s1.push(4);
 s1.push(5);
 std::cout << s1.top() << ' ' << s1.size() << std::endl;
 s1.pop();
 std::cout << s1.top() << ' ' << s1.size() << std::endl;
 s1.pop();
 s1.top();
 s1.pop();
 s1.push(6);
 s1.push(7);
 s1.push(8);
 std::cout << s1.top() << ' ' << s1.size() << std::endl;
 s1.pop();
 std::cout << s1.top() << ' ' << s1.size() << std::endl;
}

测试结果

3、使用两个栈来实现一个队列

          (1) 使用两个栈s1,s2,其中假定s1负责push操作, s2负责pop操作。使用一个变量back_elem来存储最后添加的元素。

          (2)  实现队列的push操作,  每次进行添加操作,都会相应得对栈s1进行添加元素。并对back_elem赋值

          (3) 实现队列的pop操作,每次进行删除操作,因为s2负责pop操作,

首先判断栈s2是否为空?

如果s2为空,则判断s1是否为空? 

            如果s1也为空, 则输出错误信息,此时队列为空。

            如果s1不为空,  则将栈s1中的所有数据存储到s2中。执行s2.push(s1.top()),   s1.pop().     然后在对栈s2执行,s2.pop()操作,将队列的头元素删除

如果s2不为空, 则直接对s2执行 s2.pop()操作。

           例如对a,b,c实现push操作,然后实现pop操作

                   

          (4)实现队列的front()操作,方法如pop操作相同,只是在最后一步使用s2.top()返回值。

          (5)实现队列的back()操作,因为我们变量back_elem保存着最后一个输入的数据,故直接将其返回。

          (6)实现队列的size()操作,和empty()操作,就是对s1,s2分别执行操作。

  实现代码:

#ifndef QUEUE_H
#define QUEUE_H
#include <iostream>
#include <stack>

template<typename T>
class Queue {
private:
 std::stack<T> s1;
 std::stack<T> s2;
 T back_elem;
public:
 void push(T elem);
 void pop();
 T front();
 T back();
 int size() const;
 bool empty() const;
};

template<typename T>
void Queue<T>::push(T elem) {
 s1.push(elem);
 back_elem = elem;
}

template<typename T>
void Queue<T>::pop() {
 if(!s2.empty()) {
  s2.pop();
 }
 else if(!s1.empty()) {
  while(!s1.empty()) {
   s2.push(s1.top());
   s1.pop();
  }
  s2.pop();
 }
 else {
  std::cout << "error pop(), empty queue!" << std::endl;
 }
}

template<typename T>
T Queue<T>::front(){
 if(!s2.empty()) {
  return s2.top();
 }
 else if(!s1.empty()) {
  while(!s1.empty()) {
   s2.push(s1.top());
   s1.pop();
  }
  return s2.top();
 }
 else {
  std::cout << "error front(), empty queue!" << std::endl;
 }
}

template<typename T>
T Queue<T>::back(){
 if(!empty())
  return back_elem;
 else {
  std::cout << "error back(), empty queue!" << std::endl;
  return 0;
 }
}

template<typename T>
int Queue<T>::size() const {
 return s1.size() + s2.size();
}

template<typename T>
bool Queue<T>::empty() const {
 return s1.empty() && s2.empty();
}

#endif

测试程序

#include "Queue.h"
#include <string>

int main() {
 Queue<int> queue;
 queue.push(4);
 queue.push(5);
 queue.push(6);

 std::cout << queue.front() << ' ' << queue.back() << ' ' << queue.size() << std::endl;

 queue.pop();
 queue.pop();
 std::cout << queue.front() << ' ' << queue.back() << ' ' << queue.size() << std::endl;
 queue.pop();
 queue.pop();

 Queue<std::string> queue2;
 queue2.push("Hello");
 queue2.push("World");
 queue2.push("!!!!");

 std::cout << queue2.front() << ' ' << queue2.back() << ' ' << queue2.size() << std::endl;

 queue2.pop();
 queue2.pop();
 std::cout << queue2.front() << ' ' << queue2.back() << ' ' << queue2.size() << std::endl;
 queue2.pop();
 queue2.pop();
 return true;
}

测试结果:

 


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用两个队列来模拟一个一个队列用于存储元素,另一个队列用于模拟出操作。在入操作中,将元素添加到存储队列中;在出操作中,将存储队列中的元素依次添加到模拟队列中,直到只剩下一个元素,将这个元素出,然后将模拟队列中的元素依次添加回存储队列中,即完成一次出操作。 ### 回答2: 要实现两个队列实现一份,可以按照以下方式进行操作: 首先,我们创建两个队列Q1和Q2。 入操作push): 1. 如果两个队列都为空,随意选择一个队列(比如Q1)将元素入队列。 2. 如果其中一个队列(比如Q1)不为空,将元素直接入队列Q1中。 3. 如果队列Q1为空,但队列Q2不为空,将Q2中的元素依次出队列,并入队列Q1。然后将新的元素入队列Q1。 出操作pop): 1. 如果两个队列都为空,则表示为空,无法进行出操作。 2. 如果队列Q1为空,但队列Q2不为空,将Q2中的元素依次出队列,并入队列Q1,直到只剩下一个元素。将这个元素出队列作为出元素返回。 3. 如果队列Q2为空,但队列Q1不为空,将Q1中的元素依次出队列,并入队列Q2,直到只剩下一个元素。将这个元素出队列作为出元素返回。 这样,每次入操作时,都将元素入队列Q1,而出操作时,要保证将其他元素按照的先进后出的顺序移动到另一个队列,在另一个队列中只剩下一个元素时,就是需要的元素。 这种方式通过两个队列的入队和出队操作实现的功能。 ### 回答3: 要使用两个队列实现一个,可以按照以下步骤进行操作: 1. 定义两个队列queue1和queue2,并且初始时都为空队列。 2. 入操作:将元素添加到非空的队列中。如果queue1为空,则将元素添加到queue2中;如果queue2为空,则将元素添加到queue1中。 3. 出操作:首先判断非空队列是哪一个,假设为queue1。将queue1中的元素依次出队列并入队到queue2,直到queue1中只剩下一个元素。然后将这个元素出,即为需要顶元素。 4. 交换队列:将queue1和queue2交换,这样下次入操作时,就可以将元素添加到非空队列中。 5. 判断空:为空条件为两个队列都为空。 通过以上操作,即可使用两个队列实现一个的功能。需要注意的是,由于每次出操作需要将元素依次从一个队列出队并入队到另一个队列,所以在时间复杂度上会有一定的影响。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值