1-4 在一个数组中实现两个堆栈
分数 4
作者 陈越
单位 浙江大学
本题要求在一个数组中实现两个堆栈。
函数接口定义:
1 2 3
| Stack CreateStack( int MaxSize ); bool Push( Stack S, ElementType X, int Tag ); ElementType Pop( Stack S, int Tag );
|
其中Tag是堆栈编号,取1或2;MaxSize堆栈数组的规模;Stack结构定义如下:
1 2 3 4 5 6 7
| 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。
裁判测试程序样例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| #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(); void PrintStack( Stack S, int Tag );
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; }
|
输入样例:
1 2 3 4 5 6 7 8 9 10 11 12
| 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
|
输出样例:
1 2 3 4 5 6
| 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
|
此题用的是共享栈

**定义:**利用栈底位置相对不变的特性,可以让==两个顺序栈共享==一个一维数组空间,将两个栈的栈底 分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸。
正确答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| Stack CreateStack( int MaxSize ) { Stack s; s = (Stack) malloc(sizeof (struct SNode)); s->Data = (ElementType*) malloc(MaxSize * sizeof (ElementType)); 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) { printf("Stack Full\n"); return false; } if (Tag == 1) { S->Top1++; S->Data[S->Top1] = X; } else if (Tag == 2) { S->Top2--; S->Data[S->Top2] = X; } return true; }
ElementType Pop( Stack S, int Tag ) { if (Tag == 1) { if (S->Top1 == -1) { printf("Stack %d Empty\n", Tag); return ERROR; } else { return S->Data[S->Top1--]; } } else { if (S->Top2 == S->MaxSize) { printf("Stack %d Empty\n", Tag); return ERROR; } else { return S->Data[S->Top2++]; } } }
|
我的段错误答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| Stack CreateStack( int MaxSize ) { Stack s; s = (Stack) malloc(MaxSize * sizeof (ElementType)); s->Top1 = -1; s->Top2 = MaxSize; return s; }
bool Push( Stack S, ElementType X, int Tag ) { if (S->Top1 == S->Top2 - 1) { return false; } if (Tag == 1) { S->Top1++; S->Data[S->Top1] = X; } else if (Tag == 2) { S->Top2--; S->Data[S->Top2] = X; } return true; }
ElementType Pop( Stack S, int Tag ) { if (Tag == 1) { if (S->Top1 == -1) { return 1e8; } else { return S->Data[S->Top1--]; } } else { if (S->Top2 == S->MaxSize) { return 1e8; } else { return S->Data[S->Top2++]; } } }
|
错误点1:CreateStack 函数内存分配错误
1
| s = (Stack) malloc(MaxSize * sizeof (ElementType));
|
Stack是指向结构体的指针(包含Top1、Top2、Data、MaxSize等成员),则此处分配的内存大小错误:
代码试图用MaxSize * sizeof(ElementType)分配内存,但这其实是给数据数组分配的大小,而非给栈结构体本身分配内存。
后果:s 指向的内存空间过小,无法容纳结构体的 Top1、Top2 等成员。后续访问 s->Top1、s->Top2 时,会写入未分配的内存区域,导致内存越界,触发段错误。
错误点2:结构体 Data 数组未分配内存
代码中使用 S->Data[S->Top1] 访问数据,但从未给 Data 指针分配内存:
Data 是结构体中用于存储栈元素的数组指针,需要单独分配内存(大小为 MaxSize * sizeof(ElementType))。
- 后果:
S->Data 是野指针(未初始化的指针),访问 S->Data[...] 会操作非法内存,导致段错误。
错误点3:结构体 MaxSize 成员未初始化
段错误解决后出现的答案错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| Stack CreateStack( int MaxSize ) { Stack s; s = (Stack) malloc(sizeof (struct SNode)); s->Data = (ElementType*) malloc(MaxSize * sizeof (ElementType)); 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) { return false; } if (Tag == 1) { S->Top1++; S->Data[S->Top1] = X; } else if (Tag == 2) { S->Top2--; S->Data[S->Top2] = X; } return true; }
ElementType Pop( Stack S, int Tag ) { if (Tag == 1) { if (S->Top1 == -1) { return 1e8; } else { return S->Data[S->Top1--]; } } else { if (S->Top2 == S->MaxSize) { return 1e8; } else { return S->Data[S->Top2++]; } } }
|
观察输出,要在函数中也有对应输出
1.Pop中
要加上
因为main中没有
2.Push中
要变为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ElementType Pop( Stack S, int Tag ) { if (Tag == 1) { if (S->Top1 == -1) { printf("Stack %d Empty\n", Tag); return ERROR; } else { return S->Data[S->Top1--]; } } else { if (S->Top2 == S->MaxSize) { printf("Stack %d Empty\n", Tag); return ERROR; } else { return S->Data[S->Top2++]; } } }
|
因为main中会输出的是Stack 2 is Empty!,而整个输出中会先输出一个Stack 2 Empty ,没有is,说明要在函数里面先输出一段