1.1.4 栈stack与队列queue
栈stack
部分定义参考自百度百科栈
- 栈(stack)在计算机科学中是限定仅在表尾进行插入或删除操作的线性表,,是一种后进先出(LIFO )的数据结构。
- 栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据。
- 栈是只能在某一端插入和删除的特殊线性表。
- 栈的底层实现是基于数组或者链表
- c++ stl中stack是一个容器适配器,stack默认的基础容器为deque容器(一种双端都可以进行删除插入操作的数据结构)
下面的例子说明图片来自维基百科:
Lifo_stack.png
queue队列
queue.png部分定义参考自百度百科队列
- 队列是一种特殊的线性表,是一种先进先出(FIFO)的数据结构。
- 队列只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。
- 队列的底层实现也是基于数组或者链表。
- c++ stl中queue是一个容器适配器,vector、list和deque都能够作为queue的基础容器,而与stack一样queue默认的基础容器也为deque容器
232. Implement Queue using Stacks
使用stack模拟实现queue的功能,包括push、pop、peek、empty
1.举例子-画图-解题思路
实现queue的push,意味着每次的元素都要放在stack的底部,为了完成这样的效果,我们首先需要把stack1中的元素挨个取出放到辅助栈stack2中,然后把新来的元素直接放到stack1中,最后把stack2中的元素取出来再放到stack1中。
push示意图:
stack-queue.png
pop示意图:
queue的pop即stack1的top+pop操作(c++的stack,top只返回最顶元素,不会出栈,pop才会执行出栈操作)
2. 写核心逻辑代码
class MyQueue {
public:
/** Initialize your data structure here. */
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
stack<int> stack2;
// 将stack1中的元素移动到stack2中
while(!stack1.empty())
{
stack2.push(stack1.top());
stack1.pop();
}
//将新push的元素放入stack1中
stack1.push(x);
//将stack2中的元素放回stack1中
while(!stack2.empty())
{
stack1.push(stack2.top());
stack2.pop();
}
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
//top方法只返回栈的顶值,不会出栈
int value = stack1.top();
//出栈操作是pop,但没有返回值
stack1.pop();
return value;
}
/** Get the front element. */
int peek() {
return stack1.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return stack1.empty();
}
private:
stack<int> stack1;
};
3. 边界条件-无
4. 优化
每次push元素都要把元素经历stack1-stack2-stack1这样的流程是有些浪费的。可以考虑一种lazy的方式,同样准备数据结构与算法两个stack,pushi时候新元素直接放到stack1,pop或者peek时候,先看stack2中是否有元素,有直接出栈,没有则把stack1中的元素移动到stack2中。
class MyQueue {
public:
/** Initialize your data structure here. */
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
stack1.push(x);
}
void shiftStack()
{
if(stack2.empty())
{
while(!stack1.empty())
{
stack2.push(stack1.top());
stack1.pop();
}
}
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
shiftStack();
if(!stack2.empty())
{
int value = stack2.top();
stack2.pop();
return value;
}
return 0;
}
/** Get the front element. */
int peek() {
shiftStack();
if(!stack2.empty())
{
return stack2.top();
}
return 0;
}
/** Returns whether the queue is empty. */
bool empty() {
return stack1.empty() && stack2.empty();
}
private:
stack<int> stack1,stack2;
};
5. 小结
stack 经常作为一种辅助手段实现更为复杂的一些算法(图的深度优先遍历),我们后面也会看到。常用的语言c++/java中都内置了stack的数据类型,请小伙伴们尝试理解和使用stack。框架图将在225题目的小结中一并给出。
225. Implement Stack using Queues
使用队列queue模拟实现stack的push、pop、top、empty函数
1.举例子-画图-解题思路
217-op (7).png先考虑利用queue实现stack的push函数。我们要想办法每次把push的数据放到q1(queue)的头部,这时需要借助另外一个q2(queue),push到q1前先把q1中的数据依次取出放到q2中,然后将新数据push到q1中,最后把q2中数据依次取出再放回q1中。
2. 写核心逻辑代码
class MyStack {
public:
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
queue<int> q2;
//step1 step2 将queue1中元素放到queue2中
while(!q1.empty())
{
q2.push(q1.front());
q1.pop();
}
// step2 将新元素放到queue1中
q1.push(x);
//step3 setp4 再将queue2中元素放回queue1中
while(!q2.empty())
{
q1.push(q2.front());
q2.pop();
}
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int value = q1.front();
q1.pop();
return value;
}
/** Get the top element. */
int top() {
return q1.front();
}
/** Returns whether the stack is empty. */
bool empty() {
return q1.empty();
}
private:
queue<int> q1;
};
3. 边界条件
题目已经帮我们限制了各种边界条件,不用在代码中说明
4. 优化
还有一种解法是只用一个queue来完成stack的push函数。具体思路是:将新元素push到queue1中,然后将新元素之前的各个元素依次取出来放到新元素后面,这样新元素最后就位于queue1的头部了。
//我们只重写这个push函数,其他函数的实现与未优化前的版本一致
/** Push element x onto stack. */
void push(int x) {
int length = q1.size();
q1.push(x);
while(length--)
{
q1.push(q1.front());
q1.pop();
}
}
5. 小结
queue也经常作为一种辅助手段实现更为复杂的一些算法(图的广度优先遍历),我们后面也会遇到相应的例子。常用的语言c++/java中也都内置了queue的数据类型。
怎样应对IT面试与笔试-(一)
怎样应对IT面试与笔试-(二)
怎样应对IT面试与笔试-(三)
怎样应对IT面试与笔试-(四)
怎样应对IT面试与笔试-(五)
怎样应对IT面试与笔试-(五-1)
怎样应对IT面试与笔试-(六)
怎样应对IT面试与笔试-(七)
怎样应对IT面试与笔试-(八)
怎样应对IT面试与笔试-(九)
怎样应对IT面试与笔试-(十)
怎样应对IT面试与笔试-(十一)
怎样应对IT面试与笔试-(十二)
怎样应对IT面试与笔试-(十三)
怎样应对IT面试与笔试-(十四)
怎样应对IT面试与笔试-(十五)
怎样应对IT面试与笔试-(十六)
网友评论