1 题目要求
编写一个程序模拟堆栈,要求能够模拟、入栈、出栈、返回栈顶元素等基本操作。栈中元素可用整数代替。不能使用C++模板库预定义的类型。程序运行中可输入多组入栈、出栈操作,每次操作后展示栈中元素。
2 栈的定义
typedef struct {
ElementType *base;
ElementType *top;
int stackSize;
} sqStack;
3 栈的模块
3.1 栈的初始化
void InitStack(sqStack *s) { //构造一个空栈
s->base = (ElementType *)malloc(STACK_INIT_SIZE * sizeof(STACK_INIT_SIZE));//开辟内存,并且把地址转换为int*形,存储在s->base中
if (!s->base) { //说明内存分配失败:NULL
printf("内存分配失败!");
exit(-1);//内存分配失败,程序退出
}
s->top = s->base;//让栈顶与栈尾指向同一位置
s->stackSize = STACK_INIT_SIZE;//指定栈的大小
}
注解
①s->base: 意思是指针s所指向的结构体变量的成员变量base
②malloc函数:分配内存空间的函数
③malloc前的(ElementType *):意思是将malloc分配的空间强制转换为存储ElementType类型的数据空间
④malloc如果分配内存空间失败的话,返回NULL,故而这种条件下!s->base在if条件判断中为真值,以便处理内存分配失败的问题
3.2 入栈操作
void Push(sqStack *s, ElementType e) { //实现入栈操作,其中e为待插入元素
if (s->top - s->base == s->stackSize) {//栈满,需要追加内存空间
s->base = (ElementType *)realloc(s->base, (STACK_INIT_SIZE + STACKINCREMENT) * sizeof(ElementType));
//重新分配动态存储区
if (!s->base) { //说明内存分配失败:NULL
printf("内存分配失败!");
exit(-1);//内存分配失败,程序退出
}
s->top = s->base + s->stackSize;//base指向改变,同样的top的值也应该改变
s->stackSize += STACKINCREMENT;//追加了存储空间,说明栈s的长度也发生了改变
}
*(s->top) = e;
(s->top)++;
}
3.3 出栈操作
void Pop(sqStack *s) {//出栈操作,删除栈顶元素
if (s->top == s->base) {
printf("空栈不能删除元素");
exit(-1);
}
(s->top)--;
}
3.4 获取栈顶部元素
ElementType GetTop(sqStack *s) { //返回栈顶元素
if (s->top == s->base) {
printf("空栈不能返回栈顶元素");
exit(-1);
}
return *(s->top - 1); //top指向的是栈顶元素的上一个位置,top-1指向的是栈顶元素
}
3.5 展示栈存储的元素
void ShowStack(sqStack *s) {
int i;
printf("栈内元素自顶向下的输出\n");
ElementType *temp = s->top;
while (1) {
temp--;
printf("%d ", *temp);
if (temp == s->base) {
break;
}
}
printf("\n\n");
}
4 程序代码
#include <stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 20//栈的初始容量
#define STACKINCREMENT 10//栈的补充容量
typedef int ElementType;//使用ElementType类型名代替已知类型名
typedef struct {
ElementType *base;
ElementType *top;
int stackSize;
} sqStack;
void InitStack(sqStack *s) { //构造一个空栈
s->base = (ElementType *)malloc(STACK_INIT_SIZE * sizeof(
STACK_INIT_SIZE));//开辟内存,并且把地址转换为int*形,存储在s->base中
if (!s->base) { //说明内存分配失败:NULL
printf("内存分配失败!");
exit(-1);//内存分配失败,程序退出
}
s->top = s->base;//让栈顶与栈尾指向同一位置
s->stackSize = STACK_INIT_SIZE;//指定栈的大小
}
ElementType GetTop(sqStack *s) { //返回栈顶元素
if (s->top == s->base) {
printf("空栈不能返回栈顶元素");
exit(-1);
}
return *(s->top - 1); //top指向的是栈顶元素的上一个位置,top-1指向的是栈顶元素
}
void Push(sqStack *s, ElementType e) { //实现入栈操作,其中e为待插入元素
if (s->top - s->base == s->stackSize) {//栈满,需要追加内存空间
s->base = (ElementType *)realloc(s->base, (STACK_INIT_SIZE + STACKINCREMENT) * sizeof(ElementType));
//重新分配动态存储区
if (!s->base) { //说明内存分配失败:NULL
printf("内存分配失败!");
exit(-1);//内存分配失败,程序退出
}
s->top = s->base + s->stackSize;//base指向改变,同样的top的值也应该改变
s->stackSize += STACKINCREMENT;//追加了存储空间,说明栈s的长度也发生了改变
}
*(s->top) = e;
(s->top)++;
}
void Pop(sqStack *s) {//出栈操作,删除栈顶元素
if (s->top == s->base) {
printf("空栈不能删除元素");
exit(-1);
}
(s->top)--;
}
void ShowStack(sqStack *s) {
int i;
printf("栈内元素自顶向下的输出\n");
ElementType *temp = s->top;
while (1) {
temp--;
printf("%d ", *temp);
if (temp == s->base) {
break;
}
}
printf("\n\n");
}
int main() {
sqStack stk;
InitStack(&stk);
int n, j, pushNum;
printf("*****实现入栈操作*****\n");
printf("准备给栈存储元素数量:");
scanf("%d", &n);
printf("输入n个元素值:");
for (j = 0; j < n; j++) {
scanf("%d", &pushNum);
Push(&stk, pushNum);
}
ShowStack(&stk);
printf("*****实现获取栈顶元素操作*****\n");
printf("栈顶元素为:%d\n", GetTop(&stk));
ShowStack(&stk);
printf("*****实现出栈操作*****\n");
printf("请输入想删除元素数量:");
scanf("%d", &n);
for (j = 0; j < n; j++) {
Pop(&stk);
}
ShowStack(&stk);
}