您的位置:首页 > 运维架构

栈和队列之经典(上篇)

2017-12-11 17:11 134 查看
要完成下面关于栈和队列的题目,首先要明白

栈的特性:后进先出

队列的特性:先进先出

(1)实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值的操作)的时间复杂度为O(1) 。

本题的关键是要得到栈的最小元素min,我们的第一反应可能是每次压入一个新的元素时,将栈里所有元素排序,让最小元素位于栈顶,但是这样破坏了栈的规律,它不能保证最后入栈的元素可以最先出栈。

同样,建立一个辅助栈存放最小元素,并且在最小元素出栈时我们希望能够得到次小元素,是不是可以把每次的最小元素(之前的最小元素和新压入栈的元素两者的较小值)都保存放进辅助栈,这样可以保证在每次更新后辅助栈的栈顶元素即为当前栈的最小元素。

template<class T>
class Stackwithmin
{
public:
void Push(const T x)
{
_num.push(x);
if(_min.empty()||x<=_min.top())
{
_min.push(x);//当入栈元素小于辅助栈栈顶元素,即将此元素压入辅助栈
}
}
void Pop()
{
if(_num.top()==_min.top())
{
_min.pop();
}
_num.pop();
}
T Min()
{
if(!_min.empty())
{
return _min.top();
}
}
private:
stack<T> _num;
stack<T> _min;
};
int main()
{
Stackwithmin<int> s;
s.Push(4);
s.Push(2);
s.Push(5);
s.Push(3);
cout<<s.Min()<<endl;
return 0;
}




过程图:



(2)使用两个栈实现一个队列

队列特性:先进先出

我们通过一个具体例子来分析往该队列插入和删除元素的过程。建立两个栈s1和s2,如下图:



代码实现:

class QueueByTwoStack
{
public:
QueueByTwoStack()
{}
void Push(const int& x)
{
s1.push(x);
}
void Pop()
{
if(!s2.empty())
{
cout<<s2.top()<<" ";
s2.pop();
}
else
{
while(!s1.empty())
{
s2.push(s1.top());
s2.pop();
}
}
}
const int& Front()
{
if(!s2.empty())
{
return s2.top();
}
else
{
while(!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
return s2.top();
}
}
size_t Size()
{
return s1.size()+s2.size();
}
bool Empty()
{
return s1.empty() && s2.empty();
}
private:
stack<int> s1;
stack<int> s2;
};
int main()
{
QueueByTwoStack q;
q.Push(1);
q.Push(2);
q.Push(3);
q.Push(4);
cout<<q.Front()<<endl;
cout<<q.Size()<<endl;
q.Pop();
q.Pop();
q.Pop();
q.Pop();
cout<<endl;
return 0;
}




总的来说,入队列就是直接压到s1就行了;出队列先把s1中的元素全部出栈压入到s2中,弹出s2中的栈顶元素。

(3)使用两个队列实现一个栈

我们通过一系列栈的压入和弹出操作来分析用两个队列模拟一个栈的过程。



代码实现:

#include<queue>
class StackByTwoQueue
{
public:
StackByTwoQueue()
{}
void Push(const int& x)
{
if(!q1.empty())
{
q1.push(x);
}
else
{
q2.push(x);
}
}
void Pop()
{
if(q2.empty())
{
while(q1.size()!=1)
{
q2.push(q1.front());
q1.pop();
}
cout<<q1.front()<<" ";
q1.pop();
}
else
{
while(q2.size()!=1)
{
q1.push(q2.front());
q2.pop();
}
cout<<q2.front()<<" ";
q2.pop();
}
}
const int& Top()//取栈顶
{
if(q2.empty())
{
while(q1.size()!=1)
{
q2.push(q1.front());
q1.pop();
}
return q1.front();
}
else
{
while(q2.size()!=1)
{
q1.push(q2.front());
q2.pop();
}
return q2.front();
}
}
size_t Size()
{
return q1.size() + q2.size();
}
bool Empty()
{
return (q1.empty() && q2.empty());
}
private:
queue<int> q1;
queue<int> q2;
};
int main()
{
StackByTwoQueue  s;
s.Push(1);
s.Push(2);
s.Push(3);
s.Push(4);
cout<<s.Size()<<endl;
s.Pop();
s.Pop();
s.Pop();
s.Pop();
cout<<endl;
}


结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  队列 pop push