剑指offer--用两个栈实现队列

本文介绍如何利用两个栈实现一个队列的基本操作,包括插入和删除元素;同时探讨了使用两个队列实现栈的方法。文章通过具体代码示例展示了这两种数据结构的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记录《剑指offer》上的算法题。

题目描述如下:

用两个栈实现一个队列,队列的声明如下,请实现它的两个函数appendTaildeleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。

队列的声明如下:

template <typename T>
class CQueue{
public:
    CQueue(){}
    ~CQueue(){}

    void appendTail(const T& node);
    T deleteHead();
    bool empty(){
        return (stack1.size() == 0 && stack2.size() == 0);
    }
private:
    stack<T> stack1;
    stack<T> stack2;
};

实现的代码如下:

template<typename T>
void CQueue<T>::appendTail(const T& node){
    stack1.push(node);
}

template <typename T>
T CQueue<T>::deleteHead(){
    if (stack2.size() <= 0){
        while (stack1.size() > 0){
            T& data = stack1.top();
            stack1.pop();
            stack2.push(data);
        }
    }
    if (stack2.size() == 0)
        throw std::exception("queue is empty");

    T head = stack2.top();
    stack2.pop();

    return head;
}

实现的思路是使用stack1来存储插入的数据,而需要删除的时候,先将stack1的元素都压入stack2中,此时得到的stack2的栈顶元素就是最先插入的元素,并且依次删除stack2的元素得到的元素也是按顺序插入队列的元素顺序,也就是删除的时候先弹出stack2的元素,如果它为空,则查看stack1中是否也是空,如果是空,说明队列是空,不是空,则先弹出到stack2中,然后再依次弹出stack2的元素。

相关的一个题目是用两个队列实现一个栈,实现的思路是,压入元素的时候将元素都压入非空的队列,然后在弹出元素的时候,将非空队列的元素都压入另一个空的队列,除了队尾元素,此时队尾元素就是最后压入栈的元素,也是弹出的第一个元素。

实现代码如下:

#ifndef CSTACK_H_
#define CSTACK_H_
#include<queue>
using std::queue;

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

    void append(const T& data);
    T remove();
    bool empty(){
        return q1.empty() && q2.empty();
    }
private:
    queue<T> q1;
    queue<T> q2;
};

template<typename T>
void CStack<T>::append(const T& data){
    // 插入首选非空的队列,当两个队列都空的时候,默认插入队列1
    if (q1.empty()){
        q2.push(data);
    }
    else{
        q1.push(data);
    }
}

template<typename T>
T CStack<T>::remove(){
    // 删除元素的时候,将非空的队列的所有元素,除了队尾元素外,都插入到空的队列中
    T res;
    if (q1.empty()){
        while (q2.size() > 1){
            T& data = q2.front();
            q2.pop();
            q1.push(data);
        }
        res = q2.front();
        q2.pop();
    }
    else{
        while (q1.size() > 1){
            T& data = q1.front();
            q1.pop();
            q2.push(data);
        }
        res = q1.front();
        q1.pop();
    }
    return res;
}
#endif

完整的代码例子可以查看我的Github

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

spearhead_cai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值