您好,登錄后才能下訂單哦!
棧與進棧出棧
棧:是限定在棧表尾進行插入或刪除的線性表,又稱為后進先出(LIFO)的線性表,這個特點可以形象的表示為……(鐵路調度站)
只要保證每次在棧頂操作,同一進棧順序可以有不同的出棧順序,以下是部分出棧順序
34521 25431 14532 32145 43215
那么究竟怎樣驗證一個出棧序列與一個入棧序列匹配?
思路:將進棧和出棧序列分別存在數組里,然后再創建一個輔助棧,把輸入序列中的元素依次壓入棧中,并按照出棧序列依次彈出。
將進棧和出棧序列存在兩個數組里,然后再創建一個輔助棧,把輸入序列中的元素依次壓入棧中,并按照出棧序列依次彈出。
方法:以彈出序列4,5,3,2,1為例,第一個希望被彈出的數字是4,因此需要將4先壓入棧中,而壓入棧中的序列由進棧序列決定,也就是在4進棧之前保證1,2,3都在棧里面。這個時候棧中包含4個數字,分別是1,2,3,4,其中4位于棧頂,正好對應出棧數組的第一個,彈出棧頂元素4,接下來希望彈出的元素是5,而5不在棧中,因此需要將進棧序列4之后的元素壓進去,這個時候5位于棧頂,就可以彈出來了,接下來希望被彈出的是3,2,1,在每次操作之前他們都位于棧頂,故直接彈出即可。
代碼:
#include<iostream> #include<stack> using namespace std; bool Check_Push_Pop(int* pPush,int* pPop,int length) { if(length<=0 || pPush == NULL || pPop == NULL) { return false; } int in = 0; int out = 0; stack<int> s; //s.push(pPush[0]); int index = 0; //壓入元素的個數 for(out = 0;out < length; out++) //(1)for循環控制什么 { for(in = index;in <=length; in++) //pPush[1,2,3,4,5] pPop[4,5,3,2,1] { if((s.empty())||s.top()!=pPop[out]) //(2)為什么要進行判空 { if(in == length) //(3)if檢測的是什么 { return false; } s.push(pPush[in]); ++index; } else { s.pop(); break; //跳出這層for循環,使它遍歷下一個出棧元素 } } } if(s.empty() && in == length && out==length) return true; else return false; } void Test1() { int Push[5] = {1,2,3,4,5}; int Pop[5] = {4,5,3,2,1}; if(Check_Push_Pop(Push,Pop,5)) { cout<<"輸入與輸出匹配"<<endl; } else { cout<<"輸入與輸出不匹配"<<endl; } } void Test2() { int Push[5] = {1,2,3,4,5}; int Pop[5] = {4,5,3,1,2}; if(Check_Push_Pop(Push,Pop,5)) { cout<<"輸入與輸出匹配"<<endl; } else { cout<<"輸入與輸出不匹配"<<endl; } } int main() { Test1(); //Test2(); system("pause"); return 0; }
總結:
如果下一個彈出的數字剛好是棧頂數字,那么直接彈出。如果下一個彈出的數字不在棧頂,我們把進棧序列中還沒有入棧的數字壓入輔助棧,直到把下一個需要彈出的數字壓入棧為止。如果所有的數字都壓入了棧仍找到下一個彈出的數字,那么該序列不可能是一個彈出的序列。
對于入棧序列:1 2…i…j…k…n,那么它的出棧序列中不能有k…j…i這樣的序列子集。即如果入棧序列為ABC,則出棧序列不可以是CAB。
例題:
某個棧的入隊序列為A,B,C,D,E,則可能的出棧序列為()
A . ADBEC(DBC) B. EBCAD (EBC)
C. BCDEA D. EABCD(EAB)
用上述規律可以得出選C
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。