栈、队列理论基础
栈的基本特点是先进后出;栈提供push和pop等接口,所有元素都必须符合先进后出原则;栈不提供走访功能,也不提供迭代器(iterator)
栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(可以人为控制使用哪种容器来实现栈的功能)
STL中栈往往不被归类为容器,而被归类为container adapter(容器适配器)
栈的底层实现可以是vector,deque,list
常用的SGI STL,如果没有指定底层实现的话,默认是以deque为缺省情况下栈的底层结构
可以指定vector为栈的底层实现:
std::stack<int, std::vector<int> > third; // 使用vector为底层容器的栈
队列中先进先出的数据结构,同样不允许有遍历行为,不提供迭代器, SGI STL中队列一样是以deque为缺省情况下的底部结构
也可以指定list 为起底层实现,初始化queue的语句如下:
std::queue<int, std::list<int>> third; // 定义以list为底层容器的队列
所以STL 队列也不被归类为容器,而被归类为container adapter( 容器适配器)
232. 用栈实现队列
队列的特点是先进先出,栈的特点是后进先出,队列从一头进一头出,栈的所有操作都在一端
如果只靠一个栈实现的话,在每次插入队列后,都要把栈中的元素弹出,然后装入,不容易设置变量,因此采用两个栈实现
一个输入栈(模拟队列的push操作)和一个输出栈(模拟pop操作),pop时如果输出栈中的元素为空则必须把输入栈中的元素必须全放到输出栈中,否则顺序发生错误
当两个栈都为空时,队列为空
class MyQueue {
public:
stack<int> stackIn; //输入栈
stack<int> stackOut; //输出栈
MyQueue() {
}
void push(int x) {
stackIn.push(x);
}
int pop() {
//输出栈为空时,需要将输入栈中的内容!全部导入!(否则顺序发生混乱)
if(stackOut.empty()) {
while(!stackIn.empty()) {
stackOut.push(stackIn.top());
stackIn.pop();
}
}
int result = stackOut.top();
stackOut.pop();
return result;
}
int peek() {
if(stackOut.empty()) {
while(!stackIn.empty()) {
stackOut.push(stackIn.top());
stackIn.pop();
}
}
return stackOut.top();
}
bool empty() {
return stackIn.empty() && stackOut.empty() ? true : false;
}
};
225. 用队列实现栈
队列的特点是先进先出,栈的特点是后进先出,队列从一头进一头出,栈的所有操作都在一端
通过与上题比较,如果采用两个队列实现栈,这样会比较浪费,因为另外的一个队列并不会用到
采用一个队列实现栈,当栈中弹出元素时(pop)需要记录一下队列长度,把队头元素弹出并且马上放入队尾,同时size减一,当size为1时,即为队头元素
class MyStack {
public:
queue<int> queue1;
MyStack() {
}
void push(int x) {
queue1.push(x);
}
int pop() {
int result = queue1.size();
while(result != 1) {
int tmp = queue1.front();
queue1.pop();
queue1.push(tmp);
result--;
}
int ele = queue1.front();
queue1.pop();
return ele;
}
int top() {
return queue1.back();
}
bool empty() {
return queue1.empty();
}
};