【10.5】队列-化栈为队

目录

一、题目

二、解题思路

三、代码实现


 🎬 攻城狮7号个人主页

🔥 个人专栏: 《C/C++算法》

⛺️ 君子慎独!

 🌈 大家好,欢迎来访我的博客!
⛳️ 此篇文章主要讲解算法题目:化栈为队
📚 本期文章收录在《C/C++算法》,大家有兴趣可以自行查看!
⛺️ 欢迎各位 ✔️ 点赞 👍 收藏 ⭐留言 📝!

一、题目

实现一个MyQueue类,该类用两个栈来实现一个队列。

示例:

MyQueue queue = new MyQueue();

queue.push(1);
queue.push(2);
queue.peek();  // 返回 1
queue.pop();   // 返回 1
queue.empty(); // 返回 false

说明:

  • 你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, sizeis empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。

二、解题思路

        使用两个栈来实现队列的功能:一个栈作为输入栈,专门用于接收和存储通过 push 操作传入的数据;另一个栈作为输出栈,专门用于处理 poppeek 操作。

        当执行 poppeek 操作时,如果输出栈为空,则需要将输入栈中的所有元素依次弹出并压入输出栈。这样一来,输出栈中的元素顺序就会与队列的顺序一致,即输出栈的栈顶元素对应队列的队首元素,栈底元素对应队列的队尾元素。

三、代码实现

#include <iostream>
#include <stack>
using namespace std;

class MyQueue {
private:
    stack<int> inStack, outStack; // 定义两个栈:输入栈和输出栈

    // 将输入栈中的元素转移到输出栈
    void in2out() {
        while (!inStack.empty()) {
            outStack.push(inStack.top()); // 将输入栈的栈顶元素压入输出栈
            inStack.pop(); // 弹出输入栈的栈顶元素
        }
    }

public:
    MyQueue() {} // 构造函数

    // 将元素 x 推入队列
    void push(int x) {
        inStack.push(x); // 直接将元素压入输入栈
    }

    // 弹出队列的队首元素
    int pop() {
        if (outStack.empty()) { // 如果输出栈为空,需要将输入栈的元素转移到输出栈
            in2out();
        }
        int x = outStack.top(); // 获取输出栈的栈顶元素(即队首元素)
        outStack.pop(); // 弹出输出栈的栈顶元素
        return x; // 返回队首元素
    }

    // 获取队列的队首元素(不弹出)
    int peek() {
        if (outStack.empty()) { // 如果输出栈为空,需要将输入栈的元素转移到输出栈
            in2out();
        }
        return outStack.top(); // 返回输出栈的栈顶元素(即队首元素)
    }

    // 判断队列是否为空
    bool empty() {
        return inStack.empty() && outStack.empty(); // 当输入栈和输出栈都为空时,队列为空
    }
};

int main() {
    MyQueue queue;

    // 测试 push 操作
    queue.push(1);
    queue.push(2);
    queue.push(3);

    // 测试 peek 操作
    cout << "队首元素: " << queue.peek() << endl; // 输出 1

    // 测试 pop 操作
    cout << "弹出元素: " << queue.pop() << endl; // 输出 1
    cout << "弹出元素: " << queue.pop() << endl; // 输出 2

    // 测试 empty 操作
    cout << "队列是否为空: " << (queue.empty() ? "是" : "否") << endl; // 输出 否

    // 再次测试 push 操作
    queue.push(4);

    // 测试 peek 操作
    cout << "队首元素: " << queue.peek() << endl; // 输出 3

    // 测试 pop 操作
    cout << "弹出元素: " << queue.pop() << endl; // 输出 3
    cout << "弹出元素: " << queue.pop() << endl; // 输出 4

    // 测试 empty 操作
    cout << "队列是否为空: " << (queue.empty() ? "是" : "否") << endl; // 输出 是

    return 0;
}

时间复杂度分析:

  • push 操作和 empty 操作的时间复杂度均为 O(1)

  • pop 操作和 peek 操作的均摊时间复杂度为 O(1)。这是因为每个元素最多只会被压入和弹出栈各两次,因此均摊下来每个操作的时间复杂度是常数级别。

空间复杂度分析:

  • 空间复杂度为 O(n),其中 n 是操作的总数。在最坏情况下,如果进行了 npush 操作,队列中可能会存储 n 个元素,因此需要 O(n) 的额外空间。

看到这里了还不给博主点一个:
⛳️ 点赞☀️收藏 ⭐️ 关注

💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖
再次感谢大家的支持!
你们的点赞就是博主更新最大的动力!

1. 目标 计算器的实现目标是创建一个能够进行数学运算的程序,其主要目标包 括: 1. 支持基本数学运算:实现加法、减法、乘法和除法等基本算术运算。 2. 处理运算符优先级:正确处理不同运算符的优先级,确保表达式按照 数学规则进行计算。 3. 支持括号:能够处理带有括号的表达式,按照括号的优先级进行计算。 4. 处理多位数和小数:能够正确处理多位数和带小数点的数值,并进行 准确的运算。 5. 错误处理:能够检测并处理用户输入错误的情况,如非法字符、不完 整的表达式等,并给出相应的错误提示。 6. 提供用户界面:创建一个用户友好的界面,使用户能够输入表达式并 查看计算结果。 7. 可扩展性和可维护性:使用模块的设计和合适的数据结构,使得代 码易于扩展和维护,可以方便地添加新的运算符或功能。 8. 良好的性能和效率:在处理大型表达式时,能够保持较高的计算性能 和效率,以便快速计算结果。 通过实现这些目标,计算器能够提供准确、可靠且易于使用的数学运算 功能,满足用户的计算需求,并能够适应不同的计算场景。 2. 模块划分 将计算器实现分解为多个模块可以提高代码的可维护性和可扩展性。以 下是一个可能的模块划分: 1. 用户界面模块: - 负责与用户进行交互,接收用户输入的数学表达式。 - 可以是一个命令行界面或图形用户界面(GUI)。 2. 表达式解析模块: - 将用户输入的数学表达式解析为中缀表达式。 - 可以实现中缀表达式的构建和验证。 3. 中缀转后缀模块: - 将中缀表达式转换为后缀表达式。 - 包括处理运算符优先级和括号匹配的逻辑。 4. 后缀表达式求值模块: - 根据后缀表达式计算表达式的值。 - 可以实现的操作和不同运算符的计算逻辑。 3 5. 错误处理模块: - 处理用户输入错误或计算过程中的错误情况。 - 包括错误提示和异常处理。 6. 输出模块: - 将计算结果输出给用户。 - 可以在用户界面模块中处理输出逻辑。 通过将计算器的功能划分为不同的模块,可以使代码更加清晰、模块, 并且容易进行单元测试和扩展。每个模块都可以有自己的接口和实现,使得 团成员可以独立地开发和维护各个模块。 3. 模块功能实现 3.1 表达式解析模块 要在 C 语言中实现计算器的表达式解析模块,可以按照以下步骤进行: 1. 定义所需的数据结构- 创建一个结构体来表示表达式的每个元素,包括操作数和运算符。 - 可以使用链表或数组来存储表达式的元素。 2. 实现表达式解析函数: - 创建一个函数,接受表达式字符串作为输入,并返回解析后的表达式 数据结构- 遍历表达式字符串的每个字符: - 判断当前字符是数字还是运算符。 - 如果是数字,解析连续的字符,构造操作数,并将其添加到表达式 数据结构中。 - 如果是运算符,将其添加到表达式数据结构中。 - 返回解析后的表达式数据结构。c语言
06-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

攻城狮7号

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

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

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

打赏作者

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

抵扣说明:

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

余额充值