两个队列实现一个栈

两个队列实现一个栈

1.题目描述

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

2.队列与栈

  • 栈(stack)又称为栈或堆叠,是计算机科学中一种特殊的串列形式的抽象数据类型,其特殊之处在于只能允许在链表或数组的一端(称为堆栈顶端指针,top)进行加入数据(push)和输出数据(pop)的运算。由于堆栈数据结构只允许在一端进行操作,因而按照后进先出(LIFO, Last In First Out)的原理运作。
  • 这里写图片描述
    empty() 是否为空
    size() 返回大小
    top 返回栈顶数据
    push() 栈顶压入一个数据
    pop() 抛弃栈顶数据
  • 队列(queue),是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(rear)进行插入操作,在前端(front)进行删除操作。队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加。

    empty() 是否为空
    size() 返回大小
    front() 返回队头数据
    back() 返回队尾数据
    push() 队尾压入一个数据
    pop() 抛弃队头数据
  • 在STL中,栈和队列其实都是通过双向队列来实现的,简单的限制插入和删除的方向。
template<typename _Tp, typename _Sequence = deque<_Tp> >
class stack
{
    ...
}

template<typename _Tp, typename _Sequence = deque<_Tp> >
class queue
{
    ...
}

3.实现push函数

template<typename T>
void CStack<T>::push(const T& value)
{
    if(queue1.size() >=queue2.size()){
        queue1.push(value);
    }else{
        queue2.push(value);
    }
}

通过上面代码,我们可以看出,我们是在size()更大的队列中插入数据。那么有一个队列就始终是空的,空的队列是为了我们删除元素的时候做为辅助队列。

4.pop()实现

template<typename T>
T CStack<T>::pop()
{
    if(queue1.empty()&&queue2.empty())
        throw logic_error("stack is empty");
    if(!queue2.empty())
    {
        while(queue2.size() >1)
        {
            //queue2中元素压出到queue1中
            T& value = queue2.front();
            queue2.pop();
            queue1.push(value);
        }
        T value = queue2.front();
        queue2.pop();
        return value;

    }else{
        while(queue1.size() >1)
        {
            //queue1中元素压出到queue2中
            T& value = queue1.front();
            queue1.pop();
            queue2.push(value);
        }
        T value = queue1.front();
        queue1.pop();
        return value;
    }

}

通过上面代码我们可以看出,如果两个队列都是空的,即size()是0,那么进行pop的时候,抛出异常。之后,如果a队列不为空,那么b队列做辅助队列。在a队列还剩一个元素的时候,把a队列的元素压出,放到b队列里面,则a队列中唯一的一个元素就是我们要删除的元素,同时返回此元素。当b队列不为空,同上。

5.完整代码

stack.h
#ifndef STACK_H
#define STACK_H
#include <queue>
#include <stdexcept>
#include <iostream>
#include <deque>
using namespace std;

template<typename T>
class CStack
{
public:
    CStack();
    ~CStack();
    void push(const T& value);
    T pop();
private:
    queue<T> queue1;
    queue<T> queue2;
};
template<typename T>
CStack<T>::CStack()
{

}
template<typename T>
CStack<T>::~CStack()
{

}

template<typename T>
void CStack<T>::push(const T& value)
{
    if(queue1.size() >=queue2.size()){
        queue1.push(value);
    }else{
        queue2.push(value);
    }

}

template<typename T>
T CStack<T>::pop()
{
    if(queue1.empty()&&queue2.empty())
        throw logic_error("stack is empty");
    if(!queue2.empty())
    {
        while(queue2.size() >1)
        {
            //queue2中元素压出到queue1中
            T& value = queue2.front();
            queue2.pop();
            queue1.push(value);
        }
        T value = queue2.front();
        queue2.pop();
        return value;

    }else{
        while(queue1.size() >1)
        {
            //queue1中元素压出到queue2中
            T& value = queue1.front();
            queue1.pop();
            queue2.push(value);
        }
        T value = queue1.front();
        queue1.pop();
        return value;
    }

}
#endif // STACK_H

main.cpp
#include <iostream>
#include "stack.h"
using std::cout;
using std::endl;
int main(){
    try{
        CStack<char> stack;
        stack.push('a');
        stack.push('b');
        stack.push('c');

        char head = stack.pop();
        cout <<head;

        stack.push('d');
        head = stack.pop();
        cout<<head;

        stack.push('e');
        head = stack.pop();
        cout<<head;
        head = stack.pop();
        cout<<head;
        head = stack.pop();
        cout<<head;
        head = stack.pop();
        cout<<head;
        head = stack.pop();
        cout<<head;
        head = stack.pop();
        cout<<head;
    }
    catch(exception& ex)
    {
        cout<<"\n"<<ex.what()<<endl;
    }
    return 0;
}

运行结果图:
这里写图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值