6-7 在一个数组中实现两个堆栈 (20分)
PTA—数组模拟堆栈
本题要求在一个数组中实现两个堆栈。
函数接口定义:
Stack CreateStack( int MaxSize );
bool Push( Stack S, ElementType X, int Tag );
ElementType Pop( Stack S, int Tag );
其中Tag是堆栈编号,取1或2;MaxSize堆栈数组的规模;Stack结构定义如下:
typedef int Position;
struct SNode {
ElementType *Data;
Position Top1, Top2;
int MaxSize;
};
typedef struct SNode *Stack;
注意:如果堆栈已满,Push函数必须输出“Stack Full”并且返回false;如果某堆栈是空的,则Pop函数必须输出“Stack
Tag Empty”(其中Tag是该堆栈的编号),并且返回ERROR。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#define ERROR 1e8
typedef int ElementType;
typedef enum { push, pop, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
struct SNode {
ElementType *Data;
Position Top1, Top2;
int MaxSize;
};
typedef struct SNode *Stack;
Stack CreateStack( int MaxSize );
bool Push( Stack S, ElementType X, int Tag );
ElementType Pop( Stack S, int Tag );
Operation GetOp(); /* details omitted */
void PrintStack( Stack S, int Tag ); /* details omitted */
int main()
{
int N, Tag, X;
Stack S;
int done = 0;
scanf("%d", &N);
S = CreateStack(N);
while ( !done ) {
switch( GetOp() ) {
case push:
scanf("%d %d", &Tag, &X);
if (!Push(S, X, Tag)) printf("Stack %d is Full!\n", Tag);
break;
case pop:
scanf("%d", &Tag);
X = Pop(S, Tag);
if ( X==ERROR ) printf("Stack %d is Empty!\n", Tag);
break;
case end:
PrintStack(S, 1);
PrintStack(S, 2);
done = 1;
break;
}
}
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
5
Push 1 1
Pop 2
Push 2 11
Push 1 2
Push 2 12
Pop 1
Push 2 13
Push 2 14
Push 1 3
Pop 2
End
输出样例
Stack 2 Empty
Stack 2 is Empty!
Stack Full
Stack 1 is Full!
Pop from Stack 1: 1
Pop from Stack 2: 13 12 11
思路
学过堆栈的都知道,它的原理就是将东西压入一个容器,然后拿出只能从最外边开始拿,所以我们可以很简单的用一个数组模拟一个堆栈,但是这题需要模拟两个堆栈,那么???
其实很简单,只需要将Top定在,一个头,一个尾就行了
而且必须知道的是,堆栈的尾指针指向的一定是最后一个数,而不是最后一个数的后一位
然后按照要求,写出代码…
AC代码
//这里Top1表示的是最后一个数的位置
//这里Top2表示的是最后一个数的位置
Stack CreateStack( int MaxSize )
{
Stack S;
S = (Stack)malloc(sizeof(struct SNode));
S->Data = (ElementType*)malloc(sizeof(ElementType)*MaxSize);
S->MaxSize = MaxSize;
S->Top1 = -1; //这一步初始化很重要
S->Top2 = MaxSize; //同上一步一样重要
return S;
}
bool Push( Stack S, ElementType X, int Tag )
{
if(S->Top1 == S->Top2-1) //这里Top1和Top2都指向自身堆栈的最后一个数字,所以不是相碰时堆栈已满,而是相邻
{
puts("Stack Full");
return false;
}
if(Tag == 1)
S->Data[++S->Top1] = X; //由于开始Top1是-1
else
S->Data[--S->Top2] = X; //由于开始Top2是MaxSize
return true;
}
ElementType Pop( Stack S, int Tag )
{
if(S->Top1 == -1 && Tag == 1 || S->Top2 == S->MaxSize && Tag == 2)
{//这里只有这两种情况判断
printf("Stack %d Empty\n",Tag);
return ERROR;
}
if(Tag == 1)
return S->Data[S->Top1--]; //这里是尾,所以--代表pop一个尾部的堆栈
else
return S->Data[S->Top2++]; //注意这里是头,所以++代表pop一个头部的堆栈
}
Dev测试程序
#include <stdio.h>
#include <stdlib.h>
//测试样例
/*
5
0 1 1
1 2
0 2 11
0 1 2
0 2 12
1 1
0 2 13
0 2 14
0 1 3
1 2
2
*/
#define ERROR 1e8
typedef int ElementType;
typedef enum { push, pop, end } Operation;
//typedef enum { false, true } bool;
typedef int Position;
struct SNode {
ElementType *Data;
Position Top1, Top2;
int MaxSize;
};
typedef struct SNode *Stack;
Stack CreateStack( int MaxSize );
bool Push( Stack S, ElementType X, int Tag );
ElementType Pop( Stack S, int Tag );
//Operation GetOp(); /* details omitted */
void PrintStack( Stack S, int Tag ) /* details omitted */
{
printf("Pop from Stack %d:",Tag);
if(Tag == 1)
{
while(S->Top1)
printf(" %d",S->Data[S->Top1--]);
printf(" %d",S->Data[S->Top1]);
}
else
{
while(S->Top2 != S->MaxSize-1)
printf(" %d",S->Data[++S->Top2]);
}
printf("\n");
}
int main()
{
int N, Tag, X;
Stack S;
int done = 0;
scanf("%d", &N);
S = CreateStack(N);
while ( !done ) {
int i;
scanf("%d",&i);
switch( i ) {
case 0:
scanf("%d %d", &Tag, &X);
if (!Push(S, X, Tag)) printf("Stack %d is Full!\n", Tag);
break;
case 1:
scanf("%d", &Tag);
X = Pop(S, Tag);
if ( X==ERROR ) printf("Stack %d is Empty!\n", Tag);
break;
case 2:
PrintStack(S, 1);
PrintStack(S, 2);
done = 1;
break;
}
}
return 0;
}
//这里Top1表示的是当前所指的位置
//这里Top2表示的是当前所指位置的后面一位
Stack CreateStack( int MaxSize )
{
Stack S;
S = (Stack)malloc(sizeof(struct SNode));
S->Data = (ElementType*)malloc(sizeof(ElementType)*MaxSize);
S->MaxSize = MaxSize;
S->Top1 = -1;
S->Top2 = MaxSize-1;
return S;
}
bool Push( Stack S, ElementType X, int Tag )
{
if(S->Top1 == S->Top2)
{
puts("Stack Full");
return false;
}
if(Tag == 1)
S->Data[++S->Top1] = X;
else
S->Data[S->Top2--] = X;
return true;
}
ElementType Pop( Stack S, int Tag )
{
if(S->Top1 == -1 && Tag == 1 || S->Top2 == S->MaxSize-1 && Tag == 2)
{
printf("Stack %d Empty\n",Tag);
return ERROR;
}
if(Tag == 1)
return S->Top1--;
else
return ++S->Top2;
}
-----------------------------------------------------------------------------------end