第五章 栈与队列
理论基础
-
栈提供push 和 pop 等等接口,所有元素必须符合先进后出规则,所以栈不提供走访功能,也不提供迭代器(iterator)。 不像是set 或者map 提供迭代器iterator来遍历所有元素。
-
**栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能)。**也就是说栈不是容器,而是容器适配器(container adapter)。
-
栈的底层实现可以是vector,deque,list 都是可以的。我们常用的SGI STL,如果没有指定底层实现的话,默认是以deque为缺省情况下栈的底层结构。
-
队列中先进先出的数据结构,同样不允许有遍历行为,不提供迭代器, SGI STL中队列一样是以deque为缺省情况下的底部结构。
-
stack的基本函数:
-
push(x):将x入栈
-
top():获得栈顶元素
-
pop():用以弹出栈顶元素(void)
-
empty():可以检测stack内是否为空,返回true为空,返回false为非空
-
size():返回stack内元素的个数
-
-
queue的基本函数:
-
push(x): 在队尾插入一个元素
-
pop(): 将队列中最靠前位置的元素删除,没有返回值
-
size(): 返回队列中元素个数
-
empty(): 如果队列空则返回true
-
front(): 返回队列中的第一个元素
-
back(): 返回队列中最后一个元素
-
Leetcode 232. 用栈实现队列
Link:232. 用栈实现队列
Thought:
-
在 C++ 中,this 指针是一个特殊的指针,它指向当前对象的实例。多在成员函数中使用。当一个对象的成员函数被调用时,编译器会隐式地传递该对象的地址作为 this 指针。
-
双栈实现队列,一个输入栈,一个输出栈。如图。
之后将输入栈中数据全部进入输出栈。
注:输出栈不为空时输入栈可以进入数据,但是数据不能从输入栈进入输出栈。
完整C++代码如下:
class MyQueue {
public:
stack<int> stIN;
stack<int> stOUT;
MyQueue() {}
void push(int x) { stIN.push(x); }
int pop() {
if (stOUT.empty()) {
while (!stIN.empty()) {
stOUT.push(stIN.top());
stIN.pop();
}
}
// 如果输出栈不为空,直接从输出栈弹出元素即可
int res = stOUT.top();
stOUT.pop();
return res;
}
//peek()的实现直接基于pop()
int peek() {
int res = this->pop();
stOUT.push(res);
return res;
}
bool empty() { return stIN.empty() && stOUT.empty(); }
};
/**
* 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();
*/
Leetcode 225. 用队列实现栈
链接:225. 用队列实现栈
完整C++代码如下:
class MyStack {
public:
queue<int> que1;
queue<int> que2;
MyStack() {}
void push(int x) { que1.push(x); }
//双队列实现pop()
//que2仅实现临时存储功能
int pop() {
while (que1.size() > 1) {
que2.push(que1.front());
que1.pop();
}
int res = que1.front();
que1.pop();
while (!que2.empty()) {
que1.push(que2.front());
que2.pop();
}
return res;
}
//单队列实现pop()
int pop() {
int size = que1.size();
size--;
while (size--) { // 将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部
que1.push(que1.front());
que1.pop();
}
int result = que1.front(); // 此时弹出的元素顺序就是栈的顺序了
que1.pop();
return result;
}
int top() {
return que1.back();
}
bool empty() { return que1.empty(); }
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/