最近看了個面試的帖子講的是「怎麼用兩個棧來實現佇列的操作」,好奇的我也想試下這道題目,咋一看這道題目挺簡單的呀,嗯,確實不難。先簡單講下我第一眼看到這個題目時想到的解法。講解法之前先給大家講下資料結構中的棧和佇列吧,免得有的人不明白棧和佇列,那就沒辦法繼續看下去了。
我們經常會在面試中聽到「棧」這個詞語,理解這個概念對於理解程式的執行至關重要。棧這個詞語在不同的語境中表達的含義是不同的。下面我將解釋下棧的三種含義(參考:《stack的三種含義》)。
我們這裡講的其實就是這種含義,stack是一種儲存資料的結構,特點是lifo,即後進先出(last in first out)。
這種資料結構其底層是用鍊錶來現實的,最大特點是只能操作最上面的元素,所以先進棧的被壓在下面只能後出棧。
這種資料結構通常又下面幾種方法來操作最上面的元素:
push
: 進棧
pop
: 出棧
top
: 獲取棧頂元素
empty
:判斷棧是否為空
介紹完了棧的定義,簡單說下棧和佇列的區別吧,棧的特點是先進的後出,佇列的特點是先進的先出。這道題目考查的重點還是對於棧和佇列特性的理解,其次再加上一些思考就好了。
看完這道題目我其實第一反應就覺得這道題挺簡單的,新建兩個棧s1、s2,然後當有入棧請求的時候先將s1棧中的資料依次出棧進入到s2的棧中,然後將新請求入棧的資料放入s1中,最後將s2棧中資料依次出棧進入到s1棧中。每次有出棧請求的時候將s1棧中的資料出棧就好了。這種解法應該是比較常規的解法,也比較容易想到的。
但是仔細想下這種方法效率比較低,有頻繁的出棧和入棧操作,對於效能的影響比較大,那有沒有什麼更好的方法能解決這個問題呢?其實我們可以在出棧的時候把棧底元素取出來,入棧的時候正常入棧。具體實現就是當有入棧請求的時候將資料壓入棧s1,當有出棧請求的時候將s1資料依次出棧壓入s2棧中,那麼這時s2的棧頂元素就是s1的棧底元素,最後將s2的資料又依次壓入s1中。這麼這樣的話就只有出棧的操作會有頻繁的棧操作,對於入棧來講沒有額外的棧操作。這種方法其實效率已經非常高了。
其實還有一種效率更高的方法來解決這個問題,仔細想下這麼問題,將上面的解法做個優化,將s1棧中的資料依次壓入s2中後又依次壓入s1中,**那為什麼又要將s2中的資料重新壓回s1呢?**其實這步操作可以避免,我們可以當有入棧的操作時將資料壓入s1,當有出棧操作時將s2中的資料出棧,若s2棧為空,則將s1中的資料全部依次壓入s2中,這樣的方法效率會比上面的方法更優。
下面的**就是上面提到的最後一種方法的實現:
#include #include #include #include using namespace std;
std::stacks1, s2;
int main()
else if(operation ==2)
else if(!s1.empty())
printf("queue pop num: %d\n", s2.top());
s2.pop();
}else
}else
}return 0;
}
兩個棧實現佇列 兩個佇列實現棧
1.兩個棧實現佇列 大致思路 入佇列時,將元素入棧s1,出佇列時,將s2中的元素出棧即可,如果s2為空,那麼將s1中 s1.size 1 個元素出棧,加入到s2中,然後將s1中最後乙個元素出棧,即完成了出佇列的操作 include using namespace std include includ...
兩個棧實現佇列,兩個佇列實現棧
include include include using namespace std 使用兩個棧實現佇列,實現了push,pop,front操作 其中棧s2是輔助棧,push直接在s1中插入 pop從s2中出棧,如果s2是空的,將s1倒進s2,然後再出棧,這樣減少了倒棧次數,比較高效。front就...
兩個棧實現佇列 兩個佇列實現棧
一 題目描述 用兩個棧來實現乙個佇列,完成佇列的push和pop操作。佇列中的元素為int型別。二 1 自己 基本思路 乙個棧用於壓縮,乙個專門用於彈出。因為棧是先進後出,所有的元素入棧再出棧,再入棧就可以將順序調整過來。但是沒有想到優化。class solution int pop int tem...