这道题的题目是:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出序列。
本文中有关栈的结构体定义和接口定义如下:
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
#include<stdio.h>
typedef int DataType;
#define MAXSIZE (100)
typedef struct{
DataType array[MAXSIZE];
int top;
}Stack;
//初始化
void StackInit(Stack *ps)
{
ps->top = 0;
}
//栈销毁
void StackDestory(Stack *ps)
{
ps->top = 0;
}
//栈压入
void StackPush(Stack *ps, DataType data)
{
assert(ps->top < MAXSIZE);
ps->array[ps->top++] = data;
}
//栈弹出
void StackPop(Stack *ps)
{
assert(ps->top>0);
ps->top--;
}
//栈首元素
DataType StackTop(const Stack *ps)
{
assert(ps->top > 0);
return ps->array[ps->top - 1];
}
//栈容量
int StackSize(const Stack *ps)
{
return ps->top;
}
//栈为空
int StackEmpty(const Stack *ps)
{
return ps->top == 0 ? 1 : 0;
}
解题思路分为三步骤:
(1)建立主栈A和辅助栈B,其中栈A负责元素弹出序列,辅助栈B负责元素的压入序列。
(2)如果栈B的压入元素等于栈A的栈首元素,则栈A的栈首元素直接弹出;如果栈B的压入元素不等于栈A的栈首元素,继续把入栈序列的元素压栈B,直到找到与栈A的栈首元素相等的元素为止。此时,栈A的栈首元素再弹出。
(3)若要压入栈B的元素序列已经压完,栈A中还有未弹出元素,则栈A中的元素序列不可能是一个弹出序列。
代码如下:
bool IsPopTrue(int * pPush, int * pPop, int length)
{
bool PopList = false;
if (pPush != NULL&&pPop != NULL&&length > 0)
{
int * pNextPush = pPush;
int * pNextPop = pPop;
Stack stack;
StackInit(&stack);
while (pNextPop - pPop < length)
{
while (StackEmpty(&stack) || StackTop(&stack) != *pNextPop)
{
if (pNextPush - pPush == length)
break;
StackPush(&stack, *pNextPush);
pNextPush++;
}
if (StackTop(&stack) != *pNextPop)
break;
StackPop(&stack);
pNextPop++;
}
if (StackEmpty(&stack) && pNextPop - pPop == length)
PopList = true;
}
return PopList;
}