出棧順序問題的一般解決方法


方案

  1. 設有一個棧為s
  2. 設有一隊列q,q存儲了要求的s中元素出棧的順序
  3. 設有一隊列q_push,其中存儲了元素的入棧順序
  4. 判斷棧頂元素是否可以出棧,若為空,或者不為空但是棧頂元素不是q中當前數據,則不可以出棧.否則可以出棧
  5. 若棧頂元素可以出棧,則將其進行出棧,並將q隊首元素出隊
  6. 若棧頂元素不可以出棧,則在隊列q_push中元素不為空且不等於q的隊首元素的情況下,將q_push持續出隊,並將彈出的隊首元素都入棧到s中。
  7. 當循環結束時,q_push只有空與非空兩種可能。空說明沒找到這樣一個符合要求的元素,即出棧隊列q非法,程序結束。若非空,說明找到了這樣一個元素,回到步驟4
  8. 當循環結束時,判斷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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM