首页 > 其他分享 >【笔记】栈(Stack)

【笔记】栈(Stack)

时间:2024-04-08 17:29:51浏览次数:27  
标签:ps capacity top 笔记 ST assert STDataType Stack

一、什么是栈

栈:一种特殊的线性表,其只允许在固定的一端(也就是在表尾)进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。不含任何数据元素的栈称为空栈 。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则

注意

1、栈是一个线性表,那栈就具有线性关系,即前驱后继关系。

2、定义中说是在线性表的表尾进行插入和删除操作,这里的表尾不是栈底,而是指栈顶。也就使得:栈底是固定的,最先进栈的只能在栈底。

栈的插入操作,也叫做进栈,也可以叫称为压栈,入栈。类似子弹入弹夹。

栈的删除操作,也叫做出栈,有的也叫做弹栈。类似子弹弹出弹夹。

这两种操作如下图所示。

 二、栈的顺序存储

1、栈的实现的选择

其实链表的实现可以选择数组栈或者链式栈,但相对而言数组栈的结构实现更优。因为数组在表尾上插入删除数据的代价比较小。

数组栈

链式栈: 

2、实现栈的接口函数

(1)、定义栈

//定义静态栈
#define N 10
typedef struct Stack
{
	int a[N];//数组
	int capacity;//容量空间大小
	int top;//插入的元素的个数
}ST;

定义静态栈就直接把数组长度给定死了,过后如果有需求要修改起来十分不便,所以我们就定义一个动态的栈。

//动态栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;//数组
	STDataType capacity;//容量空间大小
	STDataType top;//插入的元素的个数
}ST;

 

(2)、初始化栈

void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

(3)、释放空间

void STDestroy(ST* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

(4)、进栈

void STPush(ST* ps, STDataType x)
{
	assert(ps);
    //在进栈之前先判定栈是否为满或者为空,如果栈满或空就得扩容
	if (ps->top == ps->capacity)
	{
//判定栈中空间是否为空,如果为空直接申请4个STDataType类型的空间,如果不为空就在原空间的基础上扩容2倍
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newCapacity;
	}

	ps->a[ps->top] = x;
	ps->top++;
}

(5)、出栈

先断言栈是否初始化成功,其次再断言栈里面的数据个数是否大于0。如果栈中数据个数小于等于0,那top--就成负数。

void STPop(ST* ps)
{
	assert(ps);

	assert(ps->top > 0);

	--ps->top;
}

(6)、求栈的大小

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

 

(7)、求栈顶元素

STDataType STTop(ST* ps)
{
	assert(ps);

	assert(ps->top > 0);

	return ps->a[ps->top - 1];//因为是数组栈,如果要返回栈顶元素,则需要返回当前数组下标-1的元素
}

(8)、检查栈是否为空

bool STEmpty(ST* ps)
{
	assert(ps);

	return ps->top == 0;
}

三、完整代码

1、头文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;//数组
	STDataType capacity;//容量空间大小
	STDataType top;//插入的元素的个数
}ST;

//初始化
void STInit(ST* ps);

//释放空间
void STDestroy(ST* ps);

//进栈
void STPush(ST* ps, STDataType x);

//出栈
void STPop(ST* ps);

//栈的大小
int STSize(ST* ps);

//获取栈顶元素
STDataType STTop(ST* ps);

//检查是否为空
bool STEmpty(ST* ps);

2、源文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"

void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void STDestroy(ST* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

void STPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newCapacity;
	}

	ps->a[ps->top] = x;
	ps->top++;
}

void STPop(ST* ps)
{
	assert(ps);

	assert(ps->top > 0);

	--ps->top;
}

STDataType STTop(ST* ps)
{
	assert(ps);

	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

bool STEmpty(ST* ps)
{
	assert(ps);

	return ps->top == 0;
}

 以上就是对栈的顺序存储的实现。如有错误,还请大家在评论区指出!!!

标签:ps,capacity,top,笔记,ST,assert,STDataType,Stack
From: https://blog.csdn.net/weixin_73359101/article/details/137511141

相关文章

  • 重链剖分学习笔记
    Part.1引入重链剖分是一种用于解决树上的路径查询和修改问题的算法,他能将\(O(n)\)级别的操作转换为\(O(\logn)\)的级别,可以说十分常用。本文将带你深入解析这个算法。Part.2概念和思路在讲解本算法之前,我们先引入一些概念:轻重儿子:对于一个树上的节点\(u\),其儿子中子......
  • Python学习笔记-001
    记录一下重学python,虽然python老早就接触了,更多的还是停留在语法层面,老c++了。最近打算从头开始系统拉一下python的基础,先预计8天学完。后面还打算系统学一下Numpy,Pandas和Matplotlib。python基础教程python简介检查是否安装python,终端输入python--versionpython是一种解释......
  • SQL知识笔记
    SQL基础知识SQL知识总结innerjoin、leftjoin、rightjoin区别关于innerjoin与leftjoin之间的区别,以前以为自己搞懂了,今天从前端取参数的时候发现不是预想中的结果,才知道问题出在innerjoin上了。需求是从数据库查数据,在前端以柱形图的形式展现出来,查到的数据......
  • 数据库笔记
    数据库1.操作数据库CREATEDATABASEAAA--创建DROPDATABASEAAA--删除USEschool--使用2.创建表CREATETABLEifNOTEXISTS`tb_usear`(`id`INTNOTNULLAUTO_INCREMENTCOMMENT'序号',`age`INT(2)NOTNULLCOMMENT'年龄',`sex`VARCHAR(2)NOT......
  • 模拟CMOS集成电路学习笔记:单级放大器(1)
            放大器顾名思义是将信号进行放大,在简单电路中我们经常默认为放大是一种线性行为,即y=kx+t。在模拟集成电路中,一个放大器需要考虑的东西有很多比如功耗、线性度、最大电压摆幅、增益等等。        如图即为拉扎维先生所提到的模拟电路设计八边形法则,这......
  • 网课笔记03
    1,printf函数printf函数的作用是将参数文本输出到屏幕。"f"表示format(格式化),表示可以定制输出文本的格式。注:printf()不会在行尾自动添加换行符,运行结束后,光标就停留在输出结束的地方,不会自动换行。如果想换行,可以在文本结尾添加一个换行符\n。\n也可以放在文本内部。prin......
  • 【学习笔记】数论分块
    先看一个例子:给出正整数\(n(n\leq10^{12})\),计算:\[\sum_{i=1}^n\lfloor\frac{n}{i}\rfloor\]如果直接暴力,复杂度为\(O(n)\),无法在1s内通过,但使用数论分块(整除分块)可以将复杂度降至\(O(\sqrt{n})\)。先看个例子,当\(n=100\)时,\(i\)和\(\lfloor\frac{n}{i}\r......
  • 个人博客项目笔记_01
    1.工程搭建前端的工程运行流程:进入项目目录执行cmd命令:若是第一次启动需要依次输入如下命令:npminstallnpmrunbuildnpmrundev之后直接执行npmrundev即可!1.1新建maven工程新建maven工程blog作为父工程,然后在父工程中创建子工程blog-api向父工程的pom.xml文件......
  • 学习笔记445—白盒测试用例设计方法(语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组
    白盒测试用例设计方法(语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组合覆盖、路径覆盖、基本路径覆盖语句覆盖:每条语句至少执行一次。判定覆盖:每个判定的所有可能结果至少出现一次。(又称“分支覆盖”)条件覆盖:每个条件的所有可能结果至少执行一次。判定/条件覆盖:一个判定中的每......
  • 【学习笔记】基础数据结构:猫树
    猫树是线段树的一个特殊版本,猫树不再支持修改操作,类似\(\text{ST}\)表猫树支持高速区间查询,每次查询都只需要进行\(1\)次合并操作,设单次合并操作的复杂度为\(O(k)\),建立猫树的复杂度是\(O(kn\logn)\)的,而查询的复杂度是\(O(k)\)的一般单次查询的复杂度是\(O(1)\),所......