97.【C语言】数据结构之栈

目录

1.基本概念

2.提炼要点

3.概念选择题

4.栈的实现

栈初始化函数

入栈函数

出栈函数和栈顶函数

栈顶函数

栈销毁函数


基本概念参见王爽老师的《汇编语言 第四版》第56和57页

节选一部分

1.基本概念

注意:这里提到的数据结构中的栈有别于操作系统的栈,后者是为函数开辟栈帧空间,局部变量存储等而服务的

2.提炼要点

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

2.进行数据插入和删除\ 操作的一端称为栈顶,另一端称为栈底

3.栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则

4.压栈(push):栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶 ;出栈(pop):栈的删除操作叫做出栈,出数据也在栈顶

★★5.两种顺序:一边入栈,一边出栈;先入栈后出栈(这里容易出概念选择题)

3.概念选择题

若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是( )

A 1,4,3,2

B 2,3,4,1

C 3,1,4,2

D 3,4,2,1

答案:选C

4.栈的实现

可使用数组或链表

显然用数组更容易实现,数组具有在内存中连续存放的特点,缓存的命中率比链表高!

栈顶插入(STPush函数)

栈初始化函数

cpp 复制代码
void STInit(ST* ps)
{
	assert(ps);
	ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->a == NULL)
	{
		perror("malloc");
		return;
	}
	ps->capacity = 4;
	ps->top = 0;//top栈顶元素的下一个位置
}

一次性malloc开辟了16个字节(int*4),ps->a存储开辟空间的首地址,定义capacity=4确保之后判断push不越界

初始化时,栈中没有元素,因此ps->top=0;等待push

入栈函数

cpp 复制代码
void STPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc");
			return;
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

先判断是否越界,如果ps->top == ps->capacity,则开辟两倍的空间,将新开辟空间的指针tmp交给ps->a,ps->a[ps->top] = x;以数组的形式访问栈,ps->top++;移向下个要push的位置

出栈函数和栈顶函数

cpp 复制代码
void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));//确保不越界
	ps->top--;
}

出栈直接改变栈指针top

cpp 复制代码
bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

如果assert断言通过,返回ps->a[ps->top - 1](指的是压入栈的最后一个元素,即栈顶元素(注意有-1))

cpp 复制代码
	while (!STEmpty(&st))
	{
		printf("%d ", STTop(&st));//必须先访问栈顶元素,严格执行后进先出
		STPop(&st);
	}

ps不为NULL时,返回 ps->top == 0;

则 while (!STEmpty(&st))变成 while (!(ps->top == 0))

++注意执行的顺序:先打印栈顶元素,再将其出栈++

栈顶函数

cpp 复制代码
STDataType STTop(ST* ps)//访问栈顶元素
{
	assert(ps);
	assert(!STEmpty(ps));//确保不越界
	return ps->a[ps->top - 1];
}

栈销毁函数

cpp 复制代码
void STDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

free(ps->a);一次性销毁所有动态开辟的空间

将ps->a=NULL防止野指针,其余参数(top和capacity)置0恢复原样

相关推荐
大熊的饲养员2 分钟前
二分查找类型算法
数据结构·算法·leetcode
建群新人小猿11 分钟前
退款成功订阅消息点击后提示订单不存在
java·开发语言·前端
仙长道号-Linux真人36 分钟前
gvim添加至右键、永久修改配置、放大缩小快捷键、ctrl + c ctrl +v 直接复制粘贴、右键和还原以前版本(V)冲突
c语言·开发语言·vim
y先森40 分钟前
js实现导航栏鼠标移入时,下划线跟随鼠标滑动
开发语言·前端·javascript
chuxinweihui1 小时前
C语言项⽬实践-贪吃蛇
c语言·开发语言·数据结构·学习·链表
‘’林花谢了春红‘’1 小时前
C++ stack 容器
开发语言·c++
网络安全King1 小时前
【D04】网络安全基本命令
开发语言·网络·安全·web安全·php
7yewh1 小时前
LeetCode 力扣 热题 100道(五)最长回文子串(C++)
c语言·开发语言·c++·mcu·算法·leetcode
我叫czc1 小时前
【python笔记03】《类》
开发语言·笔记·python
菩提祖师_1 小时前
基于Java的旅游类小程序开发与优化
java·开发语言·旅游