@程序员Carl@代码随想录
目录
理论基础
理论基础篇:代码随想录 (programmercarl.com)
栈和队列是STL(C++标准库)里的两个数据结构。
补充知识:
C++标准库有多个版本,三个最普遍的STL版本:
-
HP STL 其他版本的C++ STL,一般是以HP STL为蓝本实现出来的,HP STL是C++ STL的第一个实现版本,而且开放源代码。
-
P.J.Plauger STL 由P.J.Plauger参照HP STL实现出来的,被Visual C++编译器所采用,不是开源的。
-
SGI STL 由Silicon Graphics Computer Systems公司参照HP STL实现,被Linux的C++编译器GCC所采用,SGI STL是开源软件,源码可读性甚高。
深层一点的数据结构问题:
- C++中stack(栈)和queue(队列)是容器么?
- 我们使用的stack和queue是属于哪个版本的STL?
- 我们使用的STL中stack是如何实现的?
- stack和queue提供迭代器来遍历stack空间么?
答:
- 栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能)。
所以STL中栈往往不被归类为容器,而被归类为container adapter(容器适配器). queue也不是容器,而是容器适配器。
-
SGI STL
-
栈先进后出 ,如上图。
栈的底层实现可以是vector,deque,list ,因为它是可插拔的。我们常用的SGI STL,如果没有指定底层实现的话,默认是以deque为缺省情况下栈的底层结构。
我们也可以指定vector为栈的底层结构,如下:
std::stack<int,std::vector<int>> third;
所以说栈的内部结构如下:
队列中先进先出的数据结构,同栈一样不允许有遍历行为,不提供迭代器, SGI STL中队列一样是以deque为缺省情况下的底部结构。
也可以指定list 为起底层实现,初始化queue的语句如下:
std::queue<int,std::list<int>> Queue;
4. 不提供。
232.用栈实现队列
题目以及解析:代码随想录 (programmercarl.com)
编程习惯:一定要懂得函数复用,不要只是复制粘贴,否则大工程爆出bug改都改不完。毁灭吧。
要用到两个栈stIn,stOut。
最复杂的是pop,实现思路:如果stOut不为空,将stOut的第一个元素弹出;如果stOut为空,将stIn中的所有元素转移到stOut中,再将stOut的第一个元素弹出。这样元素的顺序就不会错啦。
class MyQueue {
public:
stack<int> stIn;
stack<int> stOut;
MyQueue() {
}
void push(int x) {
stIn.push(x);
}
int pop() {
int result;
//题目中已经说了操作是合法的,所以执行pop时,队列一定不为空
if(stOut.empty()){
while(!stIn.empty()){
stOut.push(stIn.top());
stIn.pop();
}
}
result = stOut.top();
stOut.pop();
return result;
}
int peek() {
int result = this->pop();
stOut.push(result);
return result;
}
bool empty() {
return stIn.empty() && stOut.empty();
}
};
225.用队列实现栈
题目及解析:代码随想录 (programmercarl.com)
和上面那道题不同,这里用一个队列就行。下图中把两个队列改成一个队列就完美了
真是错误百出啊!见下
class MyStack {
public:
queue<int> que1;
MyStack() {
}
void push(int x) {
que1.push(x);
}
int pop() {
int size = que1.size();
size--;
while(size--){ //这里忘记--了
que1.push(que1.front());
que1.pop(); //队列pop括号里不要加东西!
}
int res = que1.front(); //不能把que1.pop()赋值给res
que1.pop();
return res; //忘记return了
}
int top() {
return que1.back(); //这里是盲点
}
bool empty() {
return que1.empty();
}
};