栈的基本操作(出栈、入栈、销毁...

系列文章目录

单链表(自用-CSDN博客

数据结构_线性表_顺序表(C语言实现+超详细逐步解析-CSDN博客

数据结构_线性表_双向链表(C语言实现+基本操作-CSDN博客

目录

一、栈基本概念、结构、图示

二、栈的基本操作

1、初始化

 代码:

创建栈

初始化栈

2、入栈

3、出栈

4、栈顶元素

5、栈中有效元素个数

6、检测栈是否为空

7、销毁栈

三、汇总


一、栈基本概念、结构、图示

栈的逻辑结构:

可以类比一个“羽毛球筒”,最先进入的羽毛球,必须等待,其他球取出,才能出来。

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。

进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。(如图所示:)

栈的物理结构:

可以用数组实现,也可以用链表实现。

二、栈的基本操作

1、初始化

 数组的结构实现更优一些。因为数组在尾插的代价比较小。

创建栈的结构体,包括栈的基本信息,数组栈顶栈的容量

 代码:

创建栈

typedef struct Stack {
	SDataType* st;//动态开辟
	int top;//栈顶
	int capacity;//容量
}ST;
初始化栈

!!!注意

top 的取值,

第一种,top  = 0,则栈顶元素在 top - 1 的位置

第二种,top  = -1,则栈顶元素在 top  的位置。

在本文中,top 取值为 0

// 初始化栈
void StackInit(ST* s) {
	assert(s);
	// 栈 s 不能为空
	//assert的作用是现计算表达式 test,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。

	s->st = NULL;
	s->top = s->capacity = 0;
}

2、入栈

注意事项:

1、栈满、栈空时,都需要对栈的空间进行扩容,使用realloc函数。

        空间开辟的规则,一般遵循,一开始开辟四个单位。

        后面扩容时,扩增为原来的2倍。

2、动态开辟问题

检查是否开辟成功。

使用完毕后,也必须使用free函数,释放掉。避免内存泄漏。

// 入栈
void StackPush(ST* s, SDataType data) {
	assert(s);

	int newcapacity;//新容量

	//栈满  栈空 条件判断
	//则需要开辟新空间,
	//栈空开辟 4个
	//栈满  开辟原先的 2倍
	if (s->capacity == s->top) {

		//栈空
		if (s->capacity == 0) {
			newcapacity = 4;
		}
		else newcapacity = s->capacity * 2;		//栈满

		SDataType* temp = (SDataType*)realloc(s->st,sizeof(SDataType) * newcapacity);
		//扩容

		//检查是否扩容成功
		if (temp == NULL) {
			perror("malloc failed");
			exit(-1);
		}
		s->st = temp;
		s->capacity = newcapacity;
	}

	s->st[s->top] = data;
	s->top++;
}

3、出栈

// 出栈
void StackPop(ST* s,SDataType* data) {
	assert(s);

	if (s->top == 0) {
		printf("栈空");
	}
	data = s->st[s->top - 1];
	s->top--;
}

4、栈顶元素

栈顶元素在 top - 1 的位置

// 获取栈顶元素
SDataType StackTop(ST* s) {
	assert(s);

	assert(s->top > 0);//栈不为空

	return s->st[s->top - 1];
}

5、栈中有效元素个数

// 获取栈中有效元素个数
int StackSize(ST* s) {
	assert(s);
	
	return s->top ;
}

6、检测栈是否为空

// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(ST* s) {
	assert(s);

	if (s->top == 0) {
		return 1;
	}
	else return 0;
}

7、销毁栈

// 销毁栈
void StackDestroy(ST* s) {
	assert(s);

	free(s->st);

	s->st = NULL;
	s->top = s->capacity = 0;

}

三、汇总

本篇文章就到此结束啦!

以下就是全篇汇总啦~

#include"Stack.h"

// 初始化栈
void StackInit(ST* s) {
	assert(s);
	// 栈 s 不能为空
	//assert的作用是现计算表达式 test,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。

	s->st = NULL;
	s->top = s->capacity = 0;
}

// 入栈
void StackPush(ST* s, SDataType data) {
	assert(s);

	int newcapacity;//新容量

	//栈满  栈空 条件判断
	//则需要开辟新空间,
	//栈空开辟 4个
	//栈满  开辟原先的 2倍
	if (s->capacity == s->top) {

		//栈空
		if (s->capacity == 0) {
			newcapacity = 4;
		}
		else newcapacity = s->capacity * 2;		//栈满

		SDataType* temp = (SDataType*)realloc(s->st,sizeof(SDataType) * newcapacity);
		//扩容

		//检查是否扩容成功
		if (temp == NULL) {
			perror("malloc failed");
			exit(-1);
		}
		s->st = temp;
		s->capacity = newcapacity;
	}

	s->st[s->top] = data;
	s->top++;
}

// 出栈
void StackPop(ST* s,SDataType* data) {
	assert(s);

	if (s->top == 0) {
		printf("栈空");
	}
	data = s->st[s->top - 1];
	s->top--;
}

// 获取栈顶元素
SDataType StackTop(ST* s) {
	assert(s);

	assert(s->top > 0);//栈不为空

	return s->st[s->top - 1];
}

// 获取栈中有效元素个数
int StackSize(ST* s) {
	assert(s);
	
	/*因为top是指向栈顶元素的最后一个位置
	假设元素为:1,2,3,4,5,那么top肯定是指向5的后一个位置
	又因为top是从0开始累加的,所以此时top肯定为5,刚好就是元素个数
	*/

	return s->top ;
}

// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(ST* s) {
	assert(s);

	if (s->top == 0) {
		return 1;
	}
	else return 0;
}

// 销毁栈
void StackDestroy(ST* s) {
	assert(s);

	free(s->st);

	s->st = NULL;
	s->top = s->capacity = 0;

}

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值