两个队列实现一个栈

两个队列实现一个栈

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. 定义两个队列queue1和queue2; 2. 将元素压入时,将元素放入queue1中; 3. 将元素弹出时,先将queue1中的元素依次出队并放入queue2中,直到queue1中只剩一个元素,将该元素出队返回即可; 4. 在弹出元素时,如果queue1中只有一个元素,直接出队返回即可,不需要将元素放入queue2中; 5. 在弹出元素时,交换queue1和queue2的指针,使得下一次弹出时可以从另一个队列中取出元素; 6. 使用两个队列实现,其空间复杂度为O(n),其中n为中元素的个数。 以下是使用C语言实现的代码: ``` #include <stdio.h> #include <stdlib.h> typedef struct Queue { int* data; int front; int rear; } Queue; typedef struct Stack { Queue* queue1; Queue* queue2; } Stack; Queue* createQueue(int size) { Queue* queue = (Queue*)malloc(sizeof(Queue)); queue->data = (int*)malloc(sizeof(int) * size); queue->front = 0; queue->rear = 0; return queue; } Stack* createStack(int size) { Stack* stack = (Stack*)malloc(sizeof(Stack)); stack->queue1 = createQueue(size); stack->queue2 = createQueue(size); return stack; } void push(Stack* stack, int value) { stack->queue1->data[stack->queue1->rear] = value; stack->queue1->rear++; } int pop(Stack* stack) { int value = 0; if(stack->queue1->front == stack->queue1->rear) { printf("Stack is empty.\n"); return -1; } while(stack->queue1->front < stack->queue1->rear - 1) { stack->queue2->data[stack->queue2->rear] = stack->queue1->data[stack->queue1->front]; stack->queue1->front++; stack->queue2->rear++; } value = stack->queue1->data[stack->queue1->front]; stack->queue1->front++; Queue* temp = stack->queue1; stack->queue1 = stack->queue2; stack->queue2 = temp; return value; } int main() { Stack* stack = createStack(10); push(stack, 1); push(stack, 2); push(stack, 3); printf("%d\n", pop(stack)); push(stack, 4); printf("%d\n", pop(stack)); printf("%d\n", pop(stack)); printf("%d\n", pop(stack)); printf("%d\n", pop(stack)); return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值