顺序问题
栈是先进后出
队列是先进先出
关于C++中的栈和队列
通常使用的stack是属于哪个版本的STL?
C++ 标准库有三个版本最为普遍
-
HP STL 其他版本的C++ STL 一般是基于这个库实现的, HP STL 是C++ 第一个实现的STL源码库,并且源代码完全公开。
-
P.J.Plauger STL 是由P.J.Plauger STL参照 HP STL实现的, 被Visual C++ 编译器所采用,并不是开源的。
-
SGI STL 是由Silicon Graphics Computer Systems 公司参照HP STL 实现,被Linux的GCC所采用, SGI STL 是开源软件,源码可读性非常的高。
栈和队列介绍
首先, 栈的顺序是先进后出
如图所示:
栈会提供push 、pop 等诸多接口,所有元素必须符合先进先出,所以栈不提供走访功能,也不提供迭代功能。不像是set或者map那样有迭代器iterator可以遍历所有元素
C++中的stack是容器吗?
栈和队列是C++ 中的两个数据结构。而栈通常在C++中并不是被归类为容器,他被归类为容器适配器(container adapter)
为什么这么说呢,因为栈使用底层容器以实现其所有的工作,对外提供统一的接口,而他的底层容器是可插拔的,也就是说我们可以控制它的底层,由我们自己决定使用哪种容器来实现栈的功能。
那么问题来了,STL中的栈是使用什么实现的呢?
栈常用的底层实现可以是vector 、 queue 、 list , 都是可以实现的, 根本的原理也逃不脱链表和数组。
我们常用的SGI STL 中,如果没有自己指定底层实现的话,默认是以deque为底层缺省状态下栈的底层。
deque 是一个双向队列,只要封住一段,另一端开通,就可以实现栈的逻辑了。
SGI STL 中, 队列底层实现缺省时,也是默认以deque实现的。
我们也可以自己指定使用vector来实现栈
std::stack<int , std::vector<int> > third
同理,队列和栈的情况是一样的。
队列同样不允许有遍历行为,不提供迭代器,实现方式也是一样的,也可以使用list来实现队列
std::queue<int , std::list<int> > third
力扣例题 : 用栈实现队列
思路:
首先,我们可以发现的是,使用一个栈是必然行不通的,我们需要至少两个栈来模拟队列的操作
在这里我们使用两个栈来模拟,一个作为输出栈,一个作为输入栈
push操作:
push操作相对简单,只需要直接将数据放入输入栈即可
pop操作:
pop操作相对复杂,输出栈如果为空时,需要将进栈数据全部导入,再从栈中弹出数据,如果输出栈不为空,则直接从输出栈中弹出数据。
empty操作:
当进栈和出栈都为空时,这个模拟队列自然就是个空队列了。
class MyQueue {
public:
stack<int> InS;
stack<int> OutS;
MyQueue() {
}
void push(int x) {
InS.push(x);
}
int pop() {
if(OutS.empty())
while(!InS.empty())
{OutS.push(InS.top());
InS.pop();}
int result = OutS.top();
OutS.pop();
return result;
}
int peek() {
int res = this -> pop();
OutS.push(res);
return res;
}
bool empty() {
return InS.empty() && OutS.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();
*/
力扣例题:用队列实现栈
思路:
因为队列先进先出的特质与栈不同,所以它模拟栈的思路和栈模拟队列的思路又不太相同。
只需要一个队列就足以完成栈的模拟
push操作:
只需将队列数据直接放入队列即可
pop操作:
只需将除最后一个元素之外的元素重新从队头加入即可,然后将原来队尾的元素变为现在的队头再弹出。
top操作:
模拟栈的top即为queue的队尾,使用queue.back()即可
class MyStack {
public:
queue<int> st;
MyStack() {
}
void push(int x) {
st.push(x);
}
int pop() {
int size = st.size();
size--;
while(size--)
{
st.push(st.front());
st.pop();
}
int res = st.front();
st.pop();
return res;
}
int top() {
return st.back();
}
bool empty() {
return st.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();
*/