棧(stack)是一種線性表,全部的插入和刪除都在表的一端進行。其中,插入被稱爲壓棧(push),刪除被稱爲彈棧(pop),因爲只能對最新被壓入的元素進行彈出,棧又被稱爲後入先出(LIFO)表。spa
對於棧,給定一個輸入序列\(1,2...n\) ,有兩個常常被說起的問題,數學
好比,對於輸入序列\(1,2,3\),咱們有如下輸出序列class
序列\(3,1,2\)是不合法的,由於輸出3時,1和2已經被壓進棧中,故而輸出時2必須在1前面,不可能出現\(3,1,2\)的輸出序列。擴展
將問題一轉化一下,因爲輸入序列已經肯定,在棧上執行的操做將惟一地決定輸出的序列,於是能夠定義壓棧操做爲S,彈棧操做爲X,使用S和X的序列來表示輸出的序列。好比\(1,2,3\)能夠用\(SXSXSX\)表示。容易看出,對於長度爲\(n\)的輸入序列,SX的序列長爲\(2n\),其中S和X各佔n個。能夠證實,SX序列和輸出序列一一對應。總結
下面解決問題1,不一樣的輸出序列的數量就是不一樣的合法SX操做序列的數量。合法的操做數等於n個S與n個X的組合數減去其中非法的組合數。根據SX在棧上的意義,非法的組合能夠以下斷定:db
好比\(XSSSXX\)就是一個非法的組合。di
這個數目被稱之爲卡特蘭數,是一個頗有用的數學結論,下面給出一個不嚴謹的推導。display
對於長度爲n的輸入序列,n個S與n個X的組合數爲\(\dbinom{2n}{n}\),對於每一個非法的組合,從左向右記到第一個非法的X,將包括這個X在內的左邊所有S和X反轉,即將
\[ XSSSXX,SXXSSX \]
轉化爲
\[ SSSSXX,XSSSSX \]
這樣,因爲在第一個非法的X左邊,S和X的數目相等,右邊S的數目要比X的數目多1。進行反轉後,整體上S的數目要比X的數目多2,即變爲由(n+1)個S與(n-1)個X的組合。每一個不合法的SX序列均可以惟一轉化爲一個這樣的組合,每一個這樣的組合也能夠惟一轉化爲不合法的SX序列。易證對於不一樣的非法序列不會映射爲相同的結果,同理兩個不一樣的(n+1)S與(n-1)X的組合也不會映射爲相同的非法序列。故卡特蘭數的結果爲
\[ C(n)=\dbinom{2n}{n} - \dbinom{2n}{n-1} \]push
命題:對於序列\(p_1p_2...p_n\),其使用棧獲得輸出序列\(S\)的充要條件爲序列中不存在\(p_i...p_j...p_k\),在\(T\)中的輸出順序爲\(p_k...p_i...p_j\)。math
證實:
在輸出的任意時刻,咱們有還未入棧的剩餘序列\(p_m...p_n\),棧內元素(棧底爲左)\(s_1...s_k\),以及順序合法的已輸出元素\(t_1t_2...t_a\),對於下一個將出如今輸出序列中的元素\(t_{a+1}\),有兩種狀況
對於狀況一,咱們只需不停地入棧直到\(t_{a+1}\)成爲棧頂元素,此時化歸爲狀況二
對於狀況二,咱們只需彈棧便可
對於狀況三,咱們證實在充分條件下其不存在。
使用反證法假設其存在。因爲\(t_{a+1}\)不爲棧頂元素,設從\(t_{a+1}\)到棧頂選取一個元素\(o_{temp}\),因爲已經存在的序列是合法的,則\(t_{a+1}\) 的輸出順序應先於\(o_{temp}\)。即\(t{a}\)先於\(t{a+1}\)先於\(o_{temp}\)。因爲現有輸出序列均是由棧彈出得到,根據棧的性質可知入棧順序\(t{a+1}\)先於\(o_{temp}\)先於\(t_a\),即在序列中,\(t{a+1}\)先於\(o_{temp}\)先於\(t_a\)。令
\[ \begin{align} t_{a+1} & = p_i \\ o_{temp}& = p_j \\ t_a & = p_k \end{align} \]
則與條件矛盾,故可證。
必要性略。
卡特蘭數爲抽籤問題的特殊形式。除卡特蘭數以外,還有一種擴展是在規定了棧長度m之後求可能的輸出序列數,這個問題比較困難,筆者目前尚未頭緒。