出棧順序問題的一般解決方法
阿新 • • 發佈:2018-11-19
方案
- 設有一個棧為s
- 設有一佇列q,q儲存了要求的s中元素出棧的順序
- 設有一佇列q_push,其中儲存了元素的入棧順序
- 判斷棧頂元素是否可以出棧,若為空,或者不為空但是棧頂元素不是q中當前資料,則不可以出棧.否則可以出棧
- 若棧頂元素可以出棧,則將其進行出棧,並將q隊首元素出隊
- 若棧頂元素不可以出棧,則在佇列q_push中元素不為空且不等於q的隊首元素的情況下,將q_push持續出隊,並將彈出的隊首元素都入棧到s中。
- 當迴圈結束時,q_push只有空與非空兩種可能。空說明沒找到這樣一個符合要求的元素,即出棧佇列q非法,程式結束。若非空,說明找到了這樣一個元素,回到步驟4
- 當迴圈結束時,判斷q是否為空,若非空,說明出棧順序不符合要求,否則,是符合要求的。
例項
題目來源:oj.hbu.cn
題目描述 已知自然數1,2,...,N(1<=N<=100)依次入棧,請問序列C1,C2,...,CN是否為合法的出棧序列 輸入 輸入包含多組測試資料。 每組測試資料的第一行為整數N(1<=N<=100),當N=0時,輸入結束。 第二行為N個正整數,以空格隔開,為出棧序列。 輸出 對於每組輸入,輸出結果為一行字串。 如給出的序列是合法的出棧序列,則輸出Yes,否則輸出No。 樣例輸入 5 3 4 2 1 5 5 3 5 1 4 2 0 樣例輸出 Yes No
程式碼
/* 這裡沒有很嚴格的使用前面提到的資料結構,而是根據題目特性進行了一些變形 這樣寫可讀性受到了一點影響,但是還是可以類比到對應的資料結構上,而且程式碼更簡潔一些 */ #include<stdio.h> typedef struct { int data[101]; int top; }stack; int main(void) { int n,a[101],j; stack s1,s2; //s1是相當於方案中的佇列q_push,這裡用了棧進行表示,沒有嚴格的使用佇列 //s2是方案中提到的棧 while(scanf("%d",&n) && n!=0) { s1.top = s2.top = -1; for(int i = 0;i < n;i++) scanf("%d",&a[i]); for(int i = n;i > 0;i--) s1.data[++s1.top] = i; //前面都是初始化操作,演算法從這裡開始 for(j = 0;j < n;) //這裡的j相當於佇列q { //棧頂元素不符合要求 if(s2.top==-1 || (s2.top!=-1 && s2.data[s2.top]!=a[j])) { //出隊入棧 while(s1.top!=-1 && s1.data[s1.top]!=a[j]) s2.data[++s2.top] = s1.data[s1.top--]; //判斷q_push是否為空,若空則程式結束 if(s1.top!=-1) s2.data[++s2.top] = s1.data[s1.top--]; else break; } //棧頂元素符合要求 else { s2.top--; j++; } } if(j!=n) printf("No\n"); else printf("Yes\n"); } return 0; }