栈的 push、 pop序列

本文探讨了如何判断一个整数序列是否可以作为特定栈操作的出栈序列。通过分析给定的入栈序列和待验证的出栈序列,文章提供了一种算法实现思路,包括使用标准栈进行模拟验证的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

输入两个整数序列。其中一个序列表示栈的push顺序,判断另一个序列有没有可能是对应的pop顺序。

如果我们希望pop的数字正好是栈顶数字,直接pop出栈即可;如果希望pop的数字目前不在栈顶,我们就到
push序列中还没有被push到栈里的数字中去搜索这个数字,并把在它之前的所有数字都push进栈。如果所有的数字都被push进栈仍然没有找到这个数字,表明该序列不可能是一个pop序列。
12
////////////////////////////////////我们来着重分析下此题:
push
序列已经固定,
push pop
------> /---->
54 32 1 / 45 32 1
| 5 |
| 4 |
| 3 |
| 2 |
|___1__|
1.
要得到45 32 1pop序列,即pop的顺序为4->5->3->2->1首先,要pop4,可让push5之前,pop4,然后push5pop5然后发现3在栈顶,直接pop 3..2..1
2.
再看一序列,
push pop
------> /---->
54 32 1 / 43 51 2
| 5 |
| 4 |
| 3 |
| 2 |
|___1__|想得到4 35 12
pop序列,是否可能? 4->3->5->1->2同样在push5之前,push43 21pop4pop 3,然后再push5pop5
2再看栈中的从底至上是 1
,由于1 2已经在栈中,所以只能先pop2,才能pop1。所以,很显然,不可能有43 51 2pop序列。所以上述那段注释的话的意思,即是,如果,一个元素在栈顶,直接pop即可。如果它不在栈顶,那么从push序列中找这个元素找到,那么push它,然后再pop它。否则,无法在 那个顺序中pop
//////////////////////////////////////
//////////////////////////////////////
push
序列已经固定,
push pop
------> /---->
54 32 1 / 35 42 1 //
可行
| 5 | 14 53 2 //亦可行,不知各位,是否已明了题意?:)..
13
| 4 |
| 3 |
| 2 |
|___1__|
///////////////////////////////////////////////今早我也来了,呵。昨晚,后来,自个又想了想,要怎么才能pop
想要的一个数列?
push
序列已经固定,
push pop
------> /---->
54 32 1 / 54 32 1
| 5 |
| 4 |
| 3 |
| 2 |
|___1__|比如,当栈中已有数列 2
1而现在我随机 要 pop4,一看, 4不在栈中,再从 push序列中,正好,4push队列中,push4进栈之前,还得把4前面的数,即3push进来,。好,现在,push3,push4,然后便是想要的结果:pop4。所以, 当我要pop一个数时, 先看这个数 在不在已经push的 栈顶, 如果直接pop它。如果,不在,那么,从push序列中,去找这个数,找到后,push它进栈,如果push队列中它的前面还有数,那么 还得把它前面数,先push进栈。如果铺设队列中没有这个数,那当然 就不是存在这个pop结果了


#include <stack>

bool IsPossiblePopOrder(const int* pPush, const int* pPop, int nLength)
{
      bool bPossible = false;
      if(pPush && pPop && nLength > 0)
      {
            const int *pNextPush = pPush;
            const int *pNextPop = pPop;
            std::stack<int> stackData;
			
            while(pNextPop - pPop < nLength)
            {
                  while(stackData.empty() || stackData.top() != *pNextPop)
                  {
                        if(!pNextPush)
                              break;

                        stackData.push(*pNextPush);

                        if(pNextPush - pPush < nLength - 1)
                              pNextPush ++;
                        else
                              pNextPush = NULL;
                  }
				  
                  if(stackData.top() != *pNextPop)
                        break;

                  stackData.pop();
                  pNextPop ++;
            }
			
            if(stackData.empty() && pNextPop - pPop == nLength)
                  bPossible = true;
			
      }

      return bPossible;
}


另外方式:

#include<iostream>
#include<stack>

const int SIZE = 5; //定义长度
using namespace std;

bool judge(int Spush[], int Spop[])
{
    stack<int> my_stack;
    int iPush = 0, iPop = 0;
    while(iPush < SIZE) 
	{
        cout << "push " << Spush[iPush] << endl; //当栈顶和pop相等时,将pop后的栈顶与pop之后的元素相比,直到不等
        my_stack.push(Spush[iPush]);     //测试
        while(!my_stack.empty() && iPop != SIZE && my_stack.top() == Spop[iPop]) 
		{   //小心数组越界
            cout << "pop " << Spop[iPop] << endl;
            iPop++;
            my_stack.pop();
        }
        iPush++;
    }

    if(iPop == SIZE)
        return true;
    else
        return false;
	
}

int main(void)
{
    int Spush[SIZE] = {5, 4, 3, 2, 1};
    int Spop[SIZE] = {4, 3, 5, 1, 2};

    if(judge(Spush, Spop))
        cout << "Yes" << endl;
    else
        cout << "No" << endl;

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值