栈和队列互相变换
栈的特点是先进后出(FILO),队列的特点是先进先出(FIFO)。清除特点的前提下,两者可以互相实现。
队列实现栈
1、双队列法:使用两个队列,Q1为主要队列,Q2为辅助队列。
方案1:入队时的时间复杂度为O(n).
入栈操做:首先将元素入队到Q2,再将Q1的全部元素依次出队并入队到Q2,此时Q2的前端元素就是新入栈的元素,将Q1和Q2的身份互换,则Q1的元素即为栈内元素。
出栈操做:由于每次Q1的队头保留的是新入栈的元素,保证栈的后入先出,即出队Q1队首元素即可。
**栈顶元素:**获取Q1队首元素即可。
**判空操做:**判空Q1即可。
class queue2stack{
public:
queue<int>q1;
queue<int>q2;
queue2stack(){
}
void push(int x){//入栈
q2.push(x);
while(!q1.empty()){
q2.push(q1.front());
q1.pop();
}
swap(q1,q2);
}
void pop(){//出栈
q1.pop();
}
int get_top(){//栈顶元素
return q1.front();
}
bool isempty(){//判空
return q1.empty();
}
int size(){//栈的元素个数
return q1.size();
}
};
2、单队列
**入栈操做:**首先获得入栈前的元素个数n,然后将元素入队到队列,再将队列中的前n个元素(除了新入栈的元素之外的全部元素)依次出队并入队到队列,此时队列的前端的元素即为新入栈的元素。
**出栈操做:**由于每次操做保证了队列的前端为栈顶元素,因此出栈操做和获得首元素的操做只需获取队列的首元素即可。
class queue2stack{
public:
queue<int>q;
queue2stack(){
}
void push(int x){
int n=q.size();
q.push(x);
while(n--){
int t=q.front();
q.pop();
q.push(t);
}
}
void pop(){
q.pop();
}
int get_top(){
return q.front();
}
bool isempty(){
return q.empty();
}
int size(){
return q.size();
}
};
栈实现队列《经典双栈法》
由于队列的特点是先进先出,所以需要两个栈。
**入队操做:**先将主栈元素全部弹入辅助栈,再将数据入栈到主栈,再把辅助栈中的元素依次弹入主栈。
**出队操做:**后加的元素沉在栈底,先进的元素在栈顶,因此直接弹栈即可。
class stack2queue{
public:
stack<int>s1;
stack<int>s2;
stack2queue(){}
void push(int x){
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
s1.push(x);
while(!s2.empty()){
s1.push(s2.top());
s2.pop();
}
}
void pop(){
s1.pop();
}
int top(){
return s1.top();
}
int size(){
return s1.size();
}
bool empty(){
return s1.empty();
}
};