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恢复原样

相关推荐
ZVAyIVqt0UFji1 小时前
go-zero负载均衡实现原理
运维·开发语言·后端·golang·负载均衡
loop lee1 小时前
Nginx - 负载均衡及其配置(Balance)
java·开发语言·github
SomeB1oody2 小时前
【Rust自学】4.1. 所有权:栈内存 vs. 堆内存
开发语言·后端·rust
toto4122 小时前
线程安全与线程不安全
java·开发语言·安全
水木流年追梦2 小时前
【python因果库实战10】为何需要因果分析
开发语言·python
人才程序员3 小时前
QML z轴(z-order)前后层级
c语言·前端·c++·qt·软件工程·用户界面·界面
w(゚Д゚)w吓洗宝宝了3 小时前
C vs C++: 一场编程语言的演变与对比
c语言·开发语言·c++
Wils0nEdwards3 小时前
Leetcode 合并两个有序链表
算法·leetcode·链表
AI人H哥会Java4 小时前
【Spring】Spring的模块架构与生态圈—Spring MVC与Spring WebFlux
java·开发语言·后端·spring·架构
开心工作室_kaic4 小时前
springboot461学生成绩分析和弱项辅助系统设计(论文+源码)_kaic
开发语言·数据库·vue.js·php·apache