棧的原則是後進先出,即插入與刪除元素均在棧頂進行。 (獲取棧頂元素:s.top() )
隊列的原則是先進先出,即插入數據在隊尾進行,刪除數據在隊頭進行。 (獲取隊頭元素:q.front() )
-
用兩個棧實現一個隊列
思路:用兩個棧,一個棧用來進隊,一個棧用來出隊,當數據進入隊列的時候,我們將其壓入一個棧,當數據出隊的時候,我們將保存在棧內的數據pop出來,將其按照出棧的順序壓入另外一個棧,然後pop棧頂的數據就實現了出隊的操作。當我們進行入隊操作的時候,可以直接將數據壓入第一個棧。
示意圖:
實現流程:
1.stack1用來push數據:將數據push到s1前需要先將s2騰空,即把s2中的數據插入到s1中,保證stack2爲空。
2.stack2用來pop數據:
當stack1不爲空時,將stack1中的數據全部pop出來,按照出棧的順序壓入stack2中,然後拿到s2的棧頂元素並將其pop即可
當stack2不爲空時,直接pop stack2的棧頂元素即可。
代碼實現:(注意:兩個棧都爲空的時候是不能進行出隊操作的)
class MyQueue {
public:
MyQueue()
{}
~MyQueue()
{}
//入隊
void push(int x) { //設置插入到s1中
while(!s2.empty())
{
s1.push(s2.top());
s2.pop();
}
s1.push(x);
}
//出隊
int pop() {
//注意:s1,s2爲空則return
if(s1.empty() && s2.empty())
return -1;
while(!s1.empty()) //將s1中元素插入s2中
{
s2.push(s1.top());
s1.pop();
}
int ret = s2.top(); //拿到s2的top
s2.pop();
return ret;
}
//獲取隊頭(即獲取轉移後的棧頂元素)
int peek() {
if(s2.empty())
{
while(!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
}
int ret = s2.top();
return ret;
}
//判空
bool empty() {
return s1.empty() && s2.empty();
}
private:
stack<int> s1;
stack<int> s2;
};
-
用兩個隊列實現一個棧
思路:要實現一個棧,那麼後進入的數據一定是先出去的。利用兩個隊列來進行數據順序的調整。當數據進入一個棧時,可以先將數據push到一個隊列當中;當需要刪除數據時,因爲隊列是先進先出的,所以我們可以將隊尾的元素保留下來,其餘元素按照出隊的順序入隊到另外一個隊列當中,然後pop第一個隊列的最後剩下的一個元素,這樣就實現了棧的刪除操作。
示意圖:
實現步驟:
1.push數據:在插入數據的時候,需要對隊列進行判斷,將數據插入到非空的隊列當中(都爲空則默認插入q1)。這樣的話pop時我們分情況討論的時候只用分隊列爲空和不爲空兩種情況,有利於代碼的編寫。
2.pop數據:在刪除數據時,我們需要將非空隊列的隊尾數據保存下來最後進行pop,其餘數據入隊到另外一個隊列當中。就這樣利用兩個隊列來對數據進行來回交換實現棧。
代碼實現:(注意:當兩個隊列都爲空的時候是沒有辦法pop數據的)
class MyStack {
public:
MyStack()
{}
~MyStack()
{}
//入棧
void push(int x) { //插入非空隊列(都爲空默認插入q1)
if(!q2.empty())
q2.push(x);
else
q1.push(x);
}
//出棧
int pop() {
if(q1.empty()&&q2.empty()) //都爲空無法pop
return -1;
int ret;
if(!q1.empty()) //q1不爲空,將q1中的size-1個元素插入q2
{
while(q1.size()!=1)
{
q2.push(q1.front());
q1.pop();
}
ret = q1.front(); //拿到q1中僅剩的一個元素
q1.pop();
}
else //q2不爲空,將q2中的size-1個元素插入q1
{
while(q2.size()!=1)
{
q1.push(q2.front());
q2.pop();
}
ret = q2.front(); //拿到q2中僅剩的一個元素
q2.pop();
}
return ret;
}
//獲取棧頂元素
int top() { //返回非空隊列的隊尾元素
if(!q1.empty())
return q1.back();
else
return q2.back();
}
//判空
bool empty() {
return q1.empty() && q2.empty();
}
private:
queue<int> q1;
queue<int> q2;
};