简单数据结构——堆栈模拟

本文详细介绍了如何使用C++实现一个简单的堆栈数据结构,包括栈的初始化、入栈、出栈、获取栈顶元素和显示栈内元素等功能。代码中通过动态内存管理和结构体来实现栈的操作,确保了栈在空间不足时能够自动扩展。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值