栈与队列理论基础
栈(Stack):FILO
队列(Queue):FIFO
栈和队列是STL(Standard Template Library C++标准库)里面的两个数据结构。
我们需要知道使用的STL是哪个版本,才能知道对应的栈和队列的实现原理
三个最为普遍的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是开源软件,源码可读性甚高。
接下来介绍的栈和队列也是SGI STL里面的数据结构, 知道了使用版本,才知道对应的底层实现。
栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能)。
所以STL中栈往往不被归类为容器,而被归类为container adapter(容器适配器)。
栈的底层实现可以是vector,deque,list 都是可以的, 主要就是数组和链表的底层实现。
SGI STL中 队列底层实现缺省情况下一样使用deque实现的。
std::stack<int, std::vector<int> > third; // 使用vector为底层容器的栈
std::queue<int, std::list<int>> third; // 定义以list为底层容器的队列
232.用栈实现队列
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 result = stOut.top();
stOut.pop();
return result;
}
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();
*/
Python解法
class MyQueue(object):
def __init__(self):
self.stIn = []
self.stOut = []
def push(self, x):
"""
:type x: int
:rtype: None
"""
self.stIn.append(x)
def pop(self):
"""
:rtype: int
"""
if self.empty():
return None
if self.stOut:
return self.stOut.pop()
else:
for i in range(len(self.stIn)):
self.stOut.append(self.stIn.pop())
return self.stOut.pop()
def peek(self):
"""
:rtype: int
"""
res = self.pop()
self.stOut.append(res)
return res
def empty(self):
"""
:rtype: bool
"""
return not self.stIn and not self.stOut
# Your MyQueue object will be instantiated and called as such:
# obj = MyQueue()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.peek()
# param_4 = obj.empty()
225. 用队列实现栈
C++解法
class MyStack {
public:
queue<int> que1;
queue<int> que2;
MyStack() {
}
void push(int x) {
que1.push(x);
}
int pop() {
int size = que1.size();
size--;
while (size--){
que2.push(que1.front());
que1.pop();
}
int result = que1.front();
que1.pop();
que1 = que2;
while (!que2.empty()){
que2.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();
*/
Python解法
class MyStack(object):
def __init__(self):
self.queue_in = deque()
self.queue_out = deque()
def push(self, x):
"""
:type x: int
:rtype: None
"""
self.queue_in.append(x)
def pop(self):
"""
:rtype: int
"""
if self.empty():
return None
for i in range(len(self.queue_in) - 1):
self.queue_out.append(self.queue_in.popleft())
self.queue_in, self.queue_out = self.queue_out, self.queue_in
return self.queue_out.popleft()
def top(self):
"""
:rtype: int
"""
if self.empty():
return None
return self.queue_in[-1]
def empty(self):
"""
:rtype: bool
"""
return len(self.queue_in) == 0
# Your MyStack object will be instantiated and called as such:
# obj = MyStack()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.top()
# param_4 = obj.empty()