出棧順序


 

      之前參加過華北計算機研究所和優酷土豆的筆試,都考到出棧順序,之前數據結構學的不到位,遇到這類題時,還着實把我愣了一會,現在總結下,省得以后再遇到這類問題,也希望能給遇到同樣問題的兄弟們一個參考。

      廢話不多說,直接上個例題。

一個棧的入棧序列是a,b,c,d,e則棧的不可能的輸出序列是:()

A edcbd         B decba           C dceab            D abcde

       棧之根本——后進先出(Last In First Out , LIFO)初次接觸到這個問題的人,或許會認為入棧abcde,所以出棧只能是edcba所以BCD都不對。

      其實是這個問題描述有歧義,應該是分段入棧的順序,也就是說,可能先入棧a,取出a,入棧b,取出b……,所以D也是可能的。

      知道這個意思了以后,就要明確這個問題的矛盾根本所在:第一次出棧d,說明什么?說明a,b,c一定早已入棧(入棧順序決定的)。那么在出棧d以后,a,b,c的出棧順序一定是c,b,a,而不用理會中間穿插着出棧了d后面的字符(因為可以再入棧,再出棧嘛)。所以立即選中C,不用猶豫,理由簡單:d出棧了,abc一定已經入棧,那么abc只能以cba的順序出棧,C不符合,OK!

      舉一個更加直觀的例子:

如棧順序是:1 2 3 4 ,如何正確理解出棧?

     (1)入棧順序是1 2 3 4,就是指這四個數依次入棧:
數據4入棧之前,1 2 3肯定已經入棧了;
數據3入棧之前,1 2肯定已經入棧了,而4還沒入棧;
數據2入棧之前,1肯定已經入棧了,而2 3 4還沒入棧;
數據1最先入棧,2 3 4還沒入棧。
    (2)既然入棧順序是1 2 3 4,3 4入棧的時候,1 2 肯定已經入棧了,怎么會在后面再入棧。
    (3)先拿4 3 1 2這個出棧序列來說,4最先出來,說明此時1 2 3(底到頂順序)還都在棧中;接下來只有3能出棧,3出來后,棧中為1 2(底到頂順序);再接下來只有2能出棧,所以如果出棧序列前兩個是4 3的話,后兩個只能是2 1。
再看個正確的出棧序列:2 4 3 1;2最先出來,說明它出來時,3 4還沒入棧,而1已入棧且還在棧中;接着是4出來,說明此時3也在棧中(3要比4先入棧),此時棧中有1 3(底到頂順序);然后只能3出棧,最后是1出棧。
     

總之,挨個看出棧序列的數據,根據入棧順序,分析它出來時,棧中應該還有誰,而有誰還沒入棧,然后分析此時可不可能是它出棧。

 

下面針對具體問題,編程來進行分析。

輸入一個壓棧序列,判斷第二個序列是否為其出棧序列。

例如:入棧序列:1 2 3 4 5 6,出棧序列,4,3,5,2,6,1

算法思想,1:根據出棧序列,入棧,直到其棧頂等於出棧元素,棧s:4,3,2,1

                 2:棧頂與出棧序列相同出棧,否則break

根據入棧序列入棧:(左為棧頂)

               棧:1 2 3 4            1 2 3                1 2 5             1 2                   1 6                1                      |空

 出棧元素: 4 3 5 2 6 1 , 4 3 5 2 6 1 ,4 35 2 6 1,4 3 5 2 6 1 ,4 3 5 26 1 ,4 3 5 2 61 ,完

    #include <iostream>  
    #include <stack>  
    using namespace std;  
    bool IsStackPopOrder(int *pushorder,int *poporder,int len)  
    {     
        bool isorder = false;  
        if(pushorder!=NULL && poporder != NULL && len > 0)  
        {  
            stack<int> s;  
            int *pnextpush = pushorder;  
            int *pnextpop = poporder;  
            while((pnextpop - poporder) < len)  
            {  
                while(s.empty()||s.top()!=*pnextpop)  
                {  
                    if((pnextpush - pushorder)==len)
						break;  
                    s.push(*pnextpush);  
                    pnextpush++;  
                }  
                if (s.top() == *pnextpop)  
                {  
                    s.pop();  
                    pnextpop++;  
                }  
                else 
					break;  
            }  
            if ((pnextpop - poporder)==len && s.empty())
				isorder = true;  
        }  
        return isorder;  
    }  
    void main()  
    {  
        int array1[7] = {1,2,3,4,5,6,7};  
        int array2[7] = {4,3,5,6,7,1,2};  
        if(IsStackPopOrder(array1,array2,7))
			cout<<"是"<<endl;  
        else 
			cout<<"否"<<endl;  
        system("pause");  
    }  

 

 

 


免責聲明!

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



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