目录
1.用栈实现队列
232. 用栈实现队列 - 力扣(LeetCode)
https://leetcode.cn/problems/implement-queue-using-stacks/
cpp
class MyQueue {
public:
MyQueue() {
}
void push(int x) {
stack1.push(x);
}
int pop() {
if (stack2.empty())
{
while (!stack1.empty())
{
stack2.push(stack1.top());
stack1.pop();
}
}
int val = stack2.top();
stack2.pop();
return val;
}
int peek() {
if (stack2.empty())
{
while (!stack1.empty())
{
stack2.push(stack1.top());
stack1.pop();
}
}
return stack2.top();
}
bool empty() {
return stack1.empty() && stack2.empty();
}
private:
std::stack<int> stack1;
std::stack<int> stack2;
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
a.核心思想
使用两个栈(主栈和辅助栈)来模拟队列的操作,主栈用于处理入队操作,辅助栈用于处理出队和查看队头操作,保证先进入主栈的元素在出队时先从主栈弹出并压入辅助栈,从而实现先进先出的队列特性。
b.思路
① push **操作:**直接将元素压入主栈。
② pop **操作:**若辅助栈为空,将主栈元素依次弹出并压入辅助栈,然后从辅助栈弹出栈顶元素;若辅助栈不为空,直接从辅助栈弹出栈顶元素。
**③ peek 操作:**与 pop 操作类似,只是不删除队头元素,返回辅助栈栈顶元素(若辅助栈为空,经过类似 pop 的转移操作后返回辅助栈栈顶元素)。
**④ empty 操作:**当主栈和辅助栈都为空时,队列为空。
c.步骤
① 定义两个栈
stack1和stack2。②
push函数:将元素压入stack1。③
pop函数:若stack2为空,将stack1元素全部转移到stack2,然后弹出stack2栈顶元素;否则直接弹出stack2栈顶元素。④
peek函数:与pop操作前期步骤相同,最后返回stack2栈顶元素但不弹出。⑤
empty函数:判断stack1和stack2是否都为空。
2.对模板的理解以及模板和虚函数区别
a.对模板的理解
模板是C++中实现泛型编程的重要机制,它允许程序员编写与类型无关的代码。模板分为函数模板和类模板:
① 函数模板: 可以定义一个通用的函数定义,通过不同类型的实际参数进行实例化,生成针对不同数据类型的函数。例如,交换两个变量的
swap函数可以定义为模板,以支持交换int、float等各种类型的变量。② 类模板: 用于创建通用的类定义,类中的成员变量或成员函数的类型可以由模板参数指定。比如,可以定义一个通用的
Array类模板,用于管理不同类型元素的数组。
模板在编译时进行实例化,编译器根据实际使用的模板参数生成具体的代码,这有助于提高代码的复用性和可维护性。
b.模板和虚函数区别
|------------|-------------------------------------------|----------------------------------------------------------------------|
| | 模板 | 虚函数 |
| 目的不同 | 主要用于实现泛型编程,使代码能够处理多种不同的数据类型,强调代码的通用性和复用性。 | 是实现运行时多态性的关键机制,允许在派生类中重新定义基类中的函数,通过基类指针或引用调用该函数时,会根据实际对象类型来决定调用哪个函数。 |
| 实现时机不同 | 在编译时实例化,编译器根据模板参数生成具体的代码。 | 在运行时通过虚函数表(vtable)来实现动态绑定,确定调用哪个函数。 |
| 代码开销不同 | 每个不同的模板实例都会生成独立的代码,可能会导致代码体积增大,但运行时效率高。 | 通过虚函数表进行动态调用,会有一定的运行时开销(如查找虚函数表的开销),但代码复用性好,不同派生类可以共享基类的接口定义。 |
希望这些内容对大家有所帮助!
感谢大家的三连支持!