栈的表示和实现

建立文件

新建三个文件:
Stack.h:函数声明
Stack.c:函数实现
main.c:函数调用

栈的设定

先入后出,类似弹夹
在这里插入图片描述
使用数组的形式进行实现,尾部做栈顶,尾插和尾删作为压栈和出栈

定义结构体
Stack.h 中写入:

typedef int STDatatype;

typedef struct Stack
{
	STDatatype* a;//存放数据
	int top;//记录当前数据的个数
	int capacity;//当前空间的最大容量
}ST;

函数调用的实现

主函数依旧使用do-while、switch语句,实现重复使用和选项操作

流程

进入程序 --> 栈的初始化(第一个函数) --> 进入循环 --> 打印菜单(第二个函数) --> 用户进行选择 --> 进入switch -->
case 1:尾插数据,压栈(第三个函数)
case 2:尾删数据,出栈(第四个函数)
case 3:打印数据(第五个函数)
case 0:退出程序,销毁栈(第六个函数)

进行函数声明

Stack.h 中写入:

void StackInit(ST* ps);//初始化
void menu();//菜单
void StackPush(ST* ps);//压栈
void StackPop(ST* ps);//出栈
void StackPrint(ST* ps);//打印
void StackDestory(ST* ps);//销毁

完成主函数

创建枚举常量
Stack.h 中写入:

enum Option
{
	Exit,
	Push,
	Pop,
	Print
};

完成主函数
main.c中写入:

int main()
{
	int input = 0;
	ST st;
	StackInit(&st);
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case Push:
			StackPush(&st);
			break;
		case Pop:
			StackPop(&st);
			break;
		case Print:
			StackPrint(&st);
			break;
		case Exit:
			StackDestory(&st);
			printf("bye bey!\n");
			break;
		default:
			printf("Seleect error, Please Select Again!\n");
			break;
		}
	} while (input);
	return 0;
}

StackInit的实现

初始化时开辟 4 个 STDatatype 的空间,top 为 0,capacity 为 4

Stack.c 中写入:

void StackInit(ST* ps)//初始化
{
	assert(ps);
	ps->a = (STDatatype*)malloc(sizeof(STDatatype) * 4);
	if (ps->a == NULL)
	{
		perror("StackInit\n");
		exit(-1);
	}
	ps->top = 0;
	ps->capacity = 4;
}

menu的实现

Stack.c 中写入:

void menu()
{
	printf("--------------------------------------\n");
	printf("********** 1、Push  2、Pop  **********\n");
	printf("********** 3、Print 0、Exit **********\n");
	printf("--------------------------------------\n");
	printf("Please Select:");
}

StackPush的实现

StackPush的实现

在数组中尾插数据,将下标为 top 的位置放入数据 x,然后 top++

void StackPush(ST* ps)//栈顶插入
{
	assert(ps);
	BuyStack(ps);//当空间不够时,开辟新空间
	STDatatype x = 0;
	printf("请输入你要插入的数据:");
	scanf("%d", &x);
	*((ps->a) + ps->top) = x;
	ps->top++;
	printf("压栈成功!\n");
}

用到了一个新函数 - BuyStack

BuyStack的实现

当空间不够时,开辟新空间

void BuyStack(ST* ps)//开辟空间
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		STDatatype* tmp = (STDatatype*)realloc(ps->a, ps->capacity * 2 * sizeof(STDatatype));
		if (tmp == NULL)
		{
			perror("BuyStack\n");
			exit(-1);
		}
		ps->a = tmp;//更新地址
		ps->capacity *= 2;
	}
}

StackPop的实现

void StackPop(ST* ps)//栈顶删除
{
	assert(ps);
	if (ps->top <= 0)//栈为空
	{
		printf("Stack is NULL!\n");
		return;
	}
	ps->top--;
}

StackPrint的实现

StackPrint的实现

由于栈的特殊性,打印出来的数据的顺序是从栈顶到栈底排列的

void StackPrint(ST* ps)
{
	assert(ps);
	ST ps1 = *ps;//不能直接使用ps,这会改变原栈的数据
	if ((&ps1)->top <= 0)//栈为空
	{
		printf("Stack is NULL!\n");
		return;
	}
	while (!StackEmpty(&ps1))
	{
		printf("%d ", StackTop(&ps1));
		StackPop(&ps1);
	}
	printf("\n");
}

用到了两个新函数
StackEmpty:判断栈是否为空
StackTop:返还栈顶数据

StackEmpty的实现

判断 top 就行

bool StackEmpty(ST* ps)//判断是否为空
{
	assert(ps);
	return ps->top == 0;
}

StackTop的实现

STDatatype StackTop(ST* ps)//返回栈顶数据
{
	assert(ps);
	if (ps->top <= 0)
	{
		printf("Stack is NULL!\n");
		exit(-1);
	}
	return ps->a[ps->top - 1];
}

StackDestory的实现

free 加 置空

void StackDestory(ST* ps)//销毁
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

栈除了用数组实现,也可以用链表实现,只不过数组更加高效一点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值