元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为
(4,5,3,2,1)
Inarr代表你的输入顺序,也就是你的入栈顺序,outarr就是输出顺序也就是你的出栈顺序。
这里纯说思想感觉不容易理解,结合程序给大家介绍一下。
void Check(int inarr[], int outarr[], int n, Stack *s1)
{
int x = 0;
int y= 0;
while (x<n)
{
if (inarr[x]==outarr[y])
{
x++;
y++;
}
Check函数都需要四个参数,两个数组,n是代表着数组中有多少个元素,也就是你入栈多少个元素,知道n之后可以控制你的循环。S1则是一个已经创建好的栈,之后会跟大家介绍这个栈有哪些作用。
首先给x和y赋值为0,然后开始判断inarr第一个元素和outarr第一个元素相等不相等,相等说明什么?相等说明这一位是合格的,直接判断下一位就可以,为什么呢?因为这说明这个元素刚进去就直接出来了,这一位是合格的可以继续判断。
如果不相等那就说明这一位合格吗?那也不一定,如果不一定还要继续判断。
else
{
if (StackSize(s1) == 0)
{
StackPush(s1, inarr[x]);
x++;
}
else
{
if (StackTop(s1) == outarr[y])
{
StackPop(s1);
y++;
}
else
{
StackPush(s1, inarr[x]);
x++;
}
}
}
不相等的话,接下来继续判断,判断当前栈是不是为空,如果为空那就说明之前没有元素入了还没有输出,那这时候没办法了只能将你这个元素放到栈里看他什么时候会输出。
如果栈不是空的,那就要看一下是不是可能你现在输出的这个元素是你之前入过栈,没输出现在输出的了,判断一下栈顶元素是不是等于你现在输出数组指定的位置的元素。如果不相等,那这时候真的是没办法了只能是将你现在的这个元素入栈。入栈之后让你的输入数组下标加一。
如果你的输入坐标走到最后的话这时候就没有必要再进行循环了,跳出while循环,这时候需要进行一个判断,如果你的输出数组也走到最后一个那就说明你的顺序已经是合法的了,但是如果没有走到最后是不是就代表着你的输出序列一定不合法呢?
也不是的,这和刚刚判断的时候一样并不是说你当前输入数组和输出数组的值不一样就直接判断下一位,很有可能是你之前入栈的序列输出,现在也是,可能你输入完成之后在栈的一些元素还没有输出,但是必须是你当前栈中的元素必须和你留下的数组中的元素顺序一模一样不能有一点错误才代表着你当前输出顺序是合法的。
if (y<5)
{
while (StackSize(s1) != 0)
{
if (outarr[y] == StackTop(s1))
{
y++;
StackPop(s1);
}
else
{
printf("不合法\n");
return;
}
}
}
printf("合法\n");
我拿这个特殊情况给大家从头到尾走一遍。
首先进来之后一个是1,一个是3,不相等并且栈是空的,这时候就要让1入栈,然后让inarr的下标加1,指向了2,这时候2要和3比较一样吗?不一样,但是你这时候栈里边有元素,就需要判断一下你的栈中的栈顶元素和当前输出的是不是一样,1和3不一样,那就继续让inarr下标往后走,指向了3,这时候3和3相等两个都往后。一个指向了4,一个指向了2,相等吗?不相等,但是这时候不能单纯的让4入栈,这时候要看一下栈中的元素,是啥,从上到下是2,1,栈顶元素是2也就是你现在输出数组的元素啊,这时候就代表这还没让输入元素的4进去前让2出来了,也是可以的,所以这时候要让2出栈,然后outarr数组下标向后移动,然后分别指向了4,和4 不用说了相等,都往后移动,分别指向5和1,和上边说的一样现在你的栈里边有啥,只有一个1了,那在5进入之前让1出来再让5进去就可以了。然后1往后移动指向5,5和5相等都往后移动,跳出循环,输出顺序合格。
这个的在写程序的时候我感觉一定要自己把各种情况都写下来在纸上跟着自己的程序走一遍吗就能发现自己的怎么走,怎么写。
#include<stdio.h> #include<stdlib.h> #define maxsize 10 typedef int Datatype; typedef struct Stack { Datatype data[10]; int top; }Stack; Stack* StackInit(Stack *S) { S = (Stack*)malloc(sizeof(Stack)*maxsize); S->top = 0; return S; } Datatype StackSize(Stack *S) { int size = S->top; return size; } void StackPush(Stack *S, Datatype x) { S->data[S->top++] = x; return; } Datatype StackPop(Stack *S) { return S->data[S->top--]; } Datatype StackTop(Stack *S) { int n = S->top - 1; return S->data[n]; } void Check(int inarr[], int outarr[], int n, Stack *s1) { int x = 0; int y= 0; while (x<n) { if (inarr[x]==outarr[y]) { x++; y++; continue; } else { if (StackSize(s1) == 0) { StackPush(s1, inarr[x]); x++; continue; } else { if (StackTop(s1) == outarr[y]) { StackPop(s1); y++; continue; } else { StackPush(s1, inarr[x]); x++; continue; } } } } if (y<5) { while (StackSize(s1) != 0) { if (outarr[y] == StackTop(s1)) { y++; StackPop(s1); } else { printf("不合法\n"); return; } } } printf("合法\n"); } int main() { Stack *s1=NULL; s1=StackInit(s1); int inarr[] = { 1, 2, 3, 4, 5 }; int outarr[] = { 3, 2,4 , 1, 5 }; Check(inarr, outarr, 5,s1); system("pause"); return 0; }