1.基礎知識
後進先出。STL中與隊列對應的類模板爲stack ,常用操作:top()
返回棧頂元素;push()
向棧頂插入元素;pop()
刪除棧頂元素;empty()
檢查容器是否爲空;size()
返回容器的元素數。所有操作都在
關於棧的實現方式,詳見: 棧與隊列-順序棧與鏈棧類模板的實現(數據結構基礎 第3周)
2.應用:棧的壓入、彈出序列
題目:輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否爲該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列1、2、3、4、5
是某棧的壓棧序列,序列4、5、3、2、1
是該壓棧序列對應的一個彈出序列, 但 4、5、3、1、2
就不可能是該壓棧序列的彈出序列。
思路分析:
建一個棧。
步驟一:開始,先放入棧中一個元素;
步驟二:然後比較棧頂元素與待出棧元素是否相同,若相同則出棧,不同則繼續往棧中放入元素,直到全部元素均已放入棧中;
步驟三:比較棧頂元素與待出棧元素是否相同,若相同則出棧,不同則由於此時已沒有新元素可放入棧中,因此表明出棧順序不合理。若棧中所有元素均可成功出棧,證明出棧順序合理。(對於給定的進棧和出棧序列,棧的操作具有唯一性。)
代碼實現
int isPopOrder(const vector<int> pushArray, const vector<int> popArray) {
if(pushArray.size() != popArray.size()) return 0;
if(pushArray.empty()) return 1;
stack<int> s;
s.push(pushArray.at(0));
int size=pushArray.size();
int indexOfInput=1;
int indexOfOutput=0;
while(indexOfInput<size){
if(s.top()==popArray.at(indexOfOutput)) {
s.pop();
indexOfOutput++;
}
else {
s.push(pushArray.at(indexOfInput));
indexOfInput++;
}
}
while(!s.empty()) {
if(s.top() == popArray.at(indexOfOutput)) {
s.pop();
indexOfOutput++;
}
else{
return 0;
}
}
return 1;
}
測試
vector<int> v1 = { 1, 2, 3, 4, 5 };
vector<int> v2 = { 4, 5, 3, 2, 1 };
vector<int> v3 = { 4, 5, 3, 1, 2 };
vector<int> v4 = {4};
vector<int> v5 = {4};
vector<int> v6 = {5};
vector<int> v7 = {4, 5};
vector<int> v8;
test(v1, v2); //功能測試
test(v1, v3);
test(v4, v5); //邊界測試
test(v4, v6);
test(v4, v7); //負面測試
test(v8, v8);
3.應用:包含min函數的棧
題目:定義棧的數據結構,請在該類型中實現一個能夠得到棧的最小元素的min函數。在該棧中,調用min、push及pop的時間複雜度均爲O(1).
分析:一句話,每壓入一個數,都把當前最小值(之前的最小元素和新壓入棧的元素兩者的較小值)保存在另一個輔助棧裏。
代碼實現
代碼中,m_data是數據棧,而m_min是輔助棧。由於程序中使用const較多,在代碼中對其做了說明。
//在一個函數聲明中,const可以修飾形參,表明它是一個輸入參數,在函數內部不能改變其值;
void StackWithMin::push(const int &value) {
m_data.push(value);
if(m_min.empty()) {
m_min.push(value);
}
else {
int preMin=m_min.top();
if(preMin<value) m_min.push(preMin);
else m_min.push(value);
}
}
void StackWithMin::pop() {
if(!m_data.empty() && !m_min.empty()) {
m_data.pop();
m_min.pop();
}
else {
throw "error";
}
}
//對於類的成員函數,若指定其爲const類型,則表明其是一個常函數,不能修改類的 成員變量;
//對於類的成員函數,有時候必須指定其返回值爲const類型,以使得其返回值不爲“左值”
//返回值爲引用,即沒有複製返回值,返回的是對象本身。注意這個對象不能使局部變量,否則函數返回時就被釋放了。
const int& StackWithMin::min() const {
if(!m_min.empty()) return m_min.top();
else throw "error";
}