XDOJ-308判断堆栈出栈序列是否有效

描述:

如果以序列“1,2,3,4”作为一个栈(初始为空)的输入,那么可得到输出序列“1,2,3,4”或“4,3,2,1”或“2,3,1,4”等等,但是肯定得不到输出序列“4,1,2,3”或“3,1,2,4”等等。请编写一个程序,判断能否通过一个栈得到给定的输出序列。

输入说明:

每组数据由两行构成,第一行只有一个整数n(<10),表示序列长度,同时表示栈的输入序列为“1,2,3,…,n”;第二行为n个整数,表示需要判断的出栈序列,整数之间以空格分隔。

输出说明:

输出一个yes或no(表示能否通过栈得到该序列)。

输入样例:

6

3 4 2 1 5 6

输出样例:

yes

提示

根据栈的后进先出特性进行判断

解决思路:

由于出栈序列有太多可能,不能一一列举出来,所以采用检验出栈序列元素的方式。循环依据是每循环一次,就会出栈一个元素,就可以对一个出栈序列元素进行检验,所以要循环n次,每次循环可分为三种情况:

      一种是栈顶元素小于出栈序列元素,那应该一直入栈,直到该出栈序列元素入栈(所以采用循环);

      一种是栈顶元素等于出栈序列元素,让栈顶元素出栈即可。然后直接进入下一次循坏,开始检验下一位出栈序列元素;

      还有一种是栈顶元素大于出栈序列元素,例如出栈序列元素要求是2,而此时栈顶元素是3,2是不能比上面的3先出栈的,直接说明这个出栈序列是得不到的,循环也没有必要继续了

如果最后栈的元素都出栈成功了,则说明可以得到该输出序列。

此外,由于一开始栈是空的,*(s.top-1)和a【i】可能没法比较,就让它先入栈一个元素

PS:本人很菜,写的可能不完全对,如果发现有疏忽的地方可以指出来(XDOJ是通过了的)

完整代码
#include<stdio.h>
#include<stdlib.h>
#define STACK_SIZE 15
typedef struct{
	int *base;
	int *top;
	int stacksize;
}SqStack;
void InitStack(SqStack *s){
	(*s).base=(int*)malloc(STACK_SIZE*sizeof(int));
	(*s).top=(*s).base;
	(*s).stacksize=STACK_SIZE;
	
}//InitStack
void Push(SqStack *s,int e){
	
	*((*s).top)=e;
	(*s).top++;
	
	
}//Push
int Pop(SqStack *s){
	int e;
	--(*s).top;
	e=*((*s).top);
	return e;
}//Pop
int main(){
	int n,i,j,result;
	int a[15];
	SqStack s;
	InitStack(&s);
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	j=1;
	for(i=0;i<n;i++){
		if(s.base==s.top){
		Push(&s,j);
		j++;	
		}
		while(*(s.top-1)<a[i]){
		Push(&s,j);
		j++;
	    }
	    if(*(s.top-1)=a[i]){
	    Pop(&s);
		continue;	
		}
	    
	    if(*(s.top-1)>a[i]){
	        result=0;
	        printf("no");
			break;	
		}
	    
	}
	if(s.top==s.base) result=1;
	if(result) printf("yes");
	else printf("no");
	return 0;
}

   

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值