栈的push、pop序列

栈的push、pop序列

        输入两个整数序列。其中一个序列表示栈的push顺序,判断另一个序列有没有可能是对应的pop顺序。为了简单起见,我们假设push序列的任意两个整数都是不相等的。比如输入的push序列是12345,那么45321就有可能是一个pop系列。因为可以有如下的pushpop序列:push 1push 2push 3push 4poppush 5poppoppoppop,这样得到的pop序列就是45321。但序列43512就不可能是push序列12345pop序列。(寻找矛盾体)

分析:首先建立一个辅助栈s,遍历pop序列中的元素p(i)。

        首先判断辅助栈s是否为空,如果s为空,则在push序列中查找p(i)的位置,此时一定可以在push序列中找到p(i),然后将push序列中在该位置之前的元素全部push到辅助栈中,并且将这些元素标记为已push,然后继续遍历pop序列。

    如果s不为空,则比较栈顶元素和p(i)是否相等,如果相等则直接弹出,继续遍历pop序列;如果不相等则在push序列中查找p(i)的位置,如果没有查找到,则说明不可能有这样的pop序列,如果找到,则将push序列中在该位置之前的元素全部push到辅助栈中,并且将这些元素标记为已push,然后继续遍历pop序列

代码如下:

#include "stdafx.h"
#include "stdlib.h"
#include <iostream>
#include <string>
#include <stack>
using namespace std;

//查找元素在数组指定起始范围内的位置
int IndexOfPushArray(int *pushArray,int start,int n,int val)
{
	for (int i=start;i<n;i++)
	{
		if (pushArray[i]==val)
			return i;
	}
	
	return -1;
}

//检查是否可能有这样的pop序列
bool IsPossiblePop(int *pushArray,int *popArray,int n)
{
	//index1记录popArray[i]在pushArray中的位置,index2记录popArray[i+1]在pushArray中的位置
	int i,j,index1=-1,index2; 
	stack<int> s; //辅助栈
	for (i=0;i<n;i++)
	{	
		//s为空,在pushArray中查找
		if (s.empty())
		{
			index1++;
			index2=IndexOfPushArray(pushArray,index1,n,popArray[i]);
			if (index2!=-1)
			{
				for (j=index1;j<index2;j++)
				{
					s.push(pushArray[j]);
				}
				index1=index2;
			}
		}
		//s不为空时,在pushArray中查找
		else
		{
			//栈顶元素等于popArray[i],直接弹出
			if (s.top()==popArray[i])
			{
				s.pop();
			}
			//栈顶元素不等于popArray[i],继续在pushArray中查找
			else
			{
				index1++;
				index2=IndexOfPushArray(pushArray,index1,n,popArray[i]);
				if (index2!=-1) //查找成功
				{
					for (j=index1;j<index2;j++)
					{
						s.push(pushArray[j]);
					}
					index1=index2;
				}
				else  //未查找到
					return false;
			}
		}
	}
	
	return true;
}

void main()
{
	int  a[]={1,2,3,4,5};
	int b1[]={4,5,3,2,1};
	int b2[]={4,3,5,1,2};
	
	cout<<IsPossiblePop(a,b1,5)<<endl; //1
	cout<<IsPossiblePop(a,b2,5)<<endl; //0
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值