数据结构————栈的讲解(超详细!!!)

news2024/9/25 3:20:50

1  栈的概念和结构

        1.1  栈的概念

栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作,进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵循后进先出(先进后出)原则。特性与栈的结构有关

        1.2  栈的结构

                                      

上述图就是栈的图,小编说过栈是有栈顶和栈底,栈顶可进行插入和删除操作,另一端是封闭的,不进行任何操作。

2  栈的实现(基于顺序表实现)

在讲解栈之前,由于栈是一种线性表,可以使用顺序表实现,也可以使用链表实现,考虑到成本,顺序表表的实现成本低,在尾部增加数据上操作更简便。

typedef int STDataType;
typedef struct stack {
    STDataType* arr;   //数组,类型可能不是一定的所以用typedef替换一下
    int capacity;  //总空间大小
    int top;      //栈顶表示
}ST;

         2.1 栈的初始化

任何一个数据结构对其进行初始化是个必备操作,将数组值为空,同时将空间大小和元素个数都置为0,代码如下:

void STInit(ST* ps)
{

    assert(ps);
    ps->arr = NULL;
    ps->capacity = ps->top = 0;  //总空间个数和有用空间个数都初始化为0
}

         2.2 栈的销毁

 有了初始化操作,自然而然就有着销毁操作,毕竟“有始有终” ,栈的销毁同样也是不难的,我们对于arr,需要判断它是否开辟了空间,如果开辟了就free掉,没有开辟就直接把栈的空间大小和栈顶都置为空就好,下面直接上代码图:

void STDestroy(ST* ps)
{
    if (ps -> arr)   //先判断是否进行动态内存开辟了
    {
        free(ps -> arr);
    }
    ps->capacity = ps->top = 0;
}

         2.3 入栈

在进行完初始化操作以后,就要进行一些正式操作了,看着入栈这个名字很高大尚,以小编的话来说这其实就是栈的尾插(栈也只能尾插,因为只能从栈顶插入),就类似下图:

                           

上面这个图就展示了入栈操作,其实就是我们在顺序表阶段写的尾插操作,首先我们需要先设置一个函数,来判断一下栈的总空间大小和栈顶是否是相等,如果相等了那就扩容,这个和顺序表的扩容是一样的,详情可以看小编之前写的那一篇,由于栈的插入只有入栈这一种,所以扩容操作直接写到函数内部就好,我们在进行完插入以后,直接往栈顶插入数据,然后让栈顶在想后走一步就好了,下面直接展示代码:

void STPush(ST* ps, STDataType x)   //类似顺序表的尾插
{
    if (ps->capacity == ps->top)
    {
        int newcaopacity = ps->capacity == 0 ? 4 : 2 * ps -> capacity;
        STDataType* arr1 = (STDataType*)realloc(ps->arr, newcaopacity * sizeof(STDataType));
        assert(arr1);
        ps->arr = arr1;
        ps->capacity = newcaopacity;
    }  //扩容完成
    ps->arr[ps->top++] = x;
}

         2.4 出栈

有入栈肯定就会有出栈,对于栈的出栈,其实就是顺序表的尾删操作,因为栈的元素只能从栈顶出,栈底是不可以出元素的,可以类比下图进行记忆:

                               

         2.5 栈是否为空

取栈顶元通过上图我们就可以知道出栈到底是什么东西,对于出栈,我们首先需要判断栈是不是空的,不然拿什么来出栈?所以此时我们得写一个布尔类型函数来判断一下此时的栈是否是空的,如果是空的返回true,不是真的返回false,此时我们进需要判断栈顶是否为0就好,下面小编直接给代码图:

bool panduan(ST * ps)
{
    assert(ps);
    return ps -> top == 0;   //这个是来判断栈是不是空了
}

       2.6  取栈顶元素

 对于上面的代码,小编其实写的很简略,其实如果写麻烦一点我们需要使用选择语句来判断一下是否为空,这里小编直接使用一句话来跳过选择语句了,这个代码的含义就是如果右边是对的那么直接返回true,如果栈顶不为0直接返回false。当我们判断完以后,可以直接进行尾删操作,很简单,我们只需呀让栈顶减一就好了,此时我们就实现了出栈操作,下面给出代码图:

void STPop(ST* ps)
{
    assert(ps);
    assert(!panduan(ps));
    ps->top--;
}

         2.7 获取栈中有效元素个数

int STSize(ST* ps)
{
    return ps->top;
}

3  代码展示

           3.1 Stack.c

#include"Stack.h"
void STInit(ST* ps)
{
    ps->arr = NULL;
    ps->capacity = ps->top = 0;  //总空间个数和有用空间个数都初始化为0
}
 
 
 
void STDestroy(ST* ps)
{
    if (ps -> arr)   //先判断是否进行动态内存开辟了
    {
        free(ps -> arr);
    }
    ps->capacity = ps->top = 0;
}
 
 
 
void STPush(ST* ps, STDataType x)   //类似顺序表的尾插
{
    if (ps->capacity == ps->top)
    {
        int newcaopacity = ps->capacity == 0 ? 4 : 2 * ps -> capacity;
        STDataType* arr1 = (STDataType*)realloc(ps->arr, newcaopacity * sizeof(STDataType));
        assert(arr1);
        ps->arr = arr1;
        ps->capacity = newcaopacity;
    }  //扩容完成
    ps->arr[ps->top++] = x;
}
 
 
bool panduan(ST * ps)
{
    assert(ps);
    return ps -> top == 0;   //这个是来判断栈是不是空了
}
 
 
void STPop(ST* ps)
{
    assert(ps);
    assert(!panduan(ps));
    ps->top--;
}
 
 
 
STDataType STTop(ST* ps)
{
    return ps->arr[ps->top - 1];
}
 
 
int STSize(ST* ps)
{
    return ps->top;
}

           3.2 Stack.h

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>   //存放布尔类型的头文件
 
 
//下面来复习一下栈的创建  
//它的底层代码是数组(也可以理解为顺序表)
typedef int STDataType;
typedef struct stack {
    STDataType* arr;   //数组,类型可能不是一定的所以用typedef替换一下
    int capacity;  //总空间大小
    int top;      //栈顶表示
}ST;
 
 
//初始化栈
void STInit(ST* ps);
 
 
//销毁栈
void STDestroy(ST* ps);
 
 
//入栈
void STPush(ST* ps, STDataType x);
 
 
//出栈
void STPop(ST* ps);
 
 
 
//取出栈顶的元素
STDataType STTop(ST* ps);
 
 
//获取栈中有效的个数
int STSize(ST* ps);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2126314.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

杂七杂八-必备软件下载

必备软件下载 学术软件工作软件tips软件 仅个人笔记使用&#xff0c;后续持续更新&#xff0c;感谢点赞关注 学术软件 幕布&#xff1a;记录各种笔记&#xff0c;文本和思维导图快捷互换边界AIchat&#xff1a;集成了多个最新大模型工具&#xff0c;功能丰富&#xff0c;推荐使…

html加载页面

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>算数模一体化</title> </head><b…

GPT-4论文阅读

GPT-4 Technical Report论文阅读 文章目录 GPT-4 Technical Report论文阅读 Abstract训练的稳定性Training processPredictable scaling训练的稳定性多么难能可贵 Capabilities考试成绩传统的benchmark语言方面的能力Visual inputsSteerability LimitationsRisks & mitigat…

初识Linux · 进程(2)

目录 前言&#xff1a; 有关进程的相关理解 前言&#xff1a; 本文会开始慢慢切入进程了&#xff0c;当然&#xff0c;切入进程之前&#xff0c;我们需要再次复习一下操作系统&#xff0c;后面接着是介绍什么是进程&#xff0c;如何查看进程&#xff0c;在Linux中对应的文件…

你真的了解电阻吗

电阻通常有下面几种表示符号。 我们用的最多的还是定值电阻。 ESP32参考设计原理图用的是折线。 GD32中参考设计原理图用的是小方框。 包括我们画原理图的时候用的基本也是小方框。 折线符号属于ANSI&#xff08;美国标准&#xff09;矩形符号属于DIN标准&#xff08;德国工业…

Linux基本

一、安装 &#xff08;一&#xff09;bios basic input / output system cpu虚拟化技术需要开启 intel amd 不同品牌进入bios快捷键不一样 &#xff08;二&#xff09;vmware 新建 配置硬件 硬盘 建议单个虚拟硬盘文件&#xff0c;比较好管理 r如果有转移的需求&#xff…

freertos 任务调度—抢占式, 时间片

FreeRTOS 操作系统支持三种调度方式&#xff1a; 抢占式调度&#xff0c;时间片调度和合作式调度。 实际应用主要是抢占式调度和时间片调度&#xff0c;合作式调度用到的很少. 1,抢占式调度 每个任务都有不同的优先级&#xff0c; 任务会一直运行直到被高优先级任务抢占或者遇到…

使用 ShuffleNet 模型在 CIFAR-100 数据集上的图像分类

简介 在深度学习领域&#xff0c;图像分类任务是衡量算法性能的重要基准。本文将介绍我们如何使用一种高效的卷积神经网络架构——ShuffleNet&#xff0c;来处理 CIFAR-100 数据集上的图像分类问题。 CIFAR-100 数据集简介 CIFAR-100 数据集是一个广泛使用的图像分类数据集&…

使用了@Bean启动成功还能注入失败?秒级解决 定位分析

文章目录 Bean 断点跟不进去为什么需要多个同类型bean怎么友好处理同类型bean【任选一种】彩蛋 Bean 断点跟不进去 结论&#xff1a;你的其他代码 或者底层依赖&#xff0c;一定有改类型的自动注入代码&#xff0c;在Spring 机制中&#xff0c;默认拒绝Bean重写&#xff0c;你…

2024年一区SCI-极光优化算法 Polar Lights Optimization-附Matlab免费代码

引言 本期介绍了一种名为极光优化算法 Polar Lights Optimization (PLO)的元启发式算法。极光是一种独特的自然奇观&#xff0c;当来自太阳风的高能粒子在地磁场和地球大气层的影响下汇聚在地球两极时&#xff0c;就会发生极光。该成果于2024年8月最新发表在国际顶级JCR 1区、…

python画图|3D直方图基础教程

前述已经完成了直方图和3D图的基本学习&#xff0c;链接如下&#xff1a; 直方图&#xff1a;python画图|水平直方图绘制-CSDN博客 3D图&#xff1a;python画图|水平直方图绘制-CSDN博客 现在我们尝试把二者结合&#xff0c;画3D直方图。 【1】官网教程 首先&#xff0c;依…

微信开放标签【wx-open-launch-weapp】使用方法,亲测好用

如果你按照微信开放标签的文档来集成&#xff0c;那么恭喜你&#xff0c;绝对&#xff08;99%&#xff09;报错&#xff0c;今天在这里给大家演示一下在vue3中正确使用wx-open-launch-weapp的方法。 第一步&#xff1a; 配置wx.config&#xff0c;这个就不过多介绍了&#xff…

上海宝钢阿赛洛引领“绿能革命”:二期屋顶光伏项目赋能“双碳”目标新篇章

在“双碳”战略的宏伟蓝图下&#xff0c;一场能源革命的浪潮正席卷而来&#xff0c;分布式光伏以其独特的魅力成为这场变革中的璀璨明星。上海宝钢阿赛洛激光拼焊有限公司积极响应国家号召&#xff0c;携手上海宝钢节能环保技术有限公司&#xff0c;于近日宣布其屋顶光伏发电项…

SpringSecurity原理解析(五):HttpSecurity 类处理流程

1、SpringSecurity 在spring boot中与SSM项目中基于配置文件的区别 通过前边的笔记我们可以知道&#xff0c;在传统的SSM项目中 SpringSecurity的使用是基于配置文件 的&#xff0c;然后spring 容器初始化的时候将 SpringSecurity 中的各种标签解析成对应的Bean对象&#xff0c…

Cortex-M3架构学习:

异常类型 Cortex-M3 在内核水平上搭载了一个异常响应系统&#xff0c;支持为数众多的系统异常和外部中断。其 中&#xff0c;编号为 1 &#xff0d; 15 的对应系统异常&#xff0c;大于等于 16 的则全是外部中断。 Cortex-M3支持的中断源数目为 240 个&#xff0c;做成芯片后…

TensorFlow深度学习框架改进K-means、SOM自组织映射聚类算法及上海招生政策影响分析研究|附代码数据

全文链接&#xff1a;https://tecdat.cn/?p37652 原文出处&#xff1a;拓端数据部落公众号 分析师&#xff1a;Chen Zhang 在教育政策研究领域&#xff0c;准确评估政策对不同区域和学生群体的影响至关重要。2021 年上海市出台的《上海市初中学业水平考试实施办法》对招生…

PDF转Excel小达人养成记

在现代职场&#xff0c;数据管理与格式转换可谓是日常任务的重头戏&#xff1b;有时我们手头有一份PDF文件&#xff0c;但需要将其中的数据整理成Excel表格&#xff0c;这该如何是好&#xff1f;别急&#xff0c;今天我就来给大家介绍几款好用的PDF转Excel工具&#xff0c;以及…

使用您自己的图像微调 FLUX.1 LORA 并使用 Azure 机器学习进行部署

目录 介绍 了解 Flux.1 模型系列 什么是 Dreambooth&#xff1f; 先决条件 使用 Dreambooth 微调 Flux 的步骤 步骤 1&#xff1a;设置环境 第 2 步&#xff1a;加载库 步骤 3&#xff1a;准备数据集 3.1 通过 AML 数据资产&#xff08;URI 文件夹&#xff09;将图像上传到…

minio集群

1 集群部署 minio集群的搭建并不复杂&#xff0c;别人也有很多的例子&#xff0c;这里只是先把自己的集群搭建记录下来&#xff0c;重点是后面的章节&#xff0c;遇到问题如何解决。 1.1 修改主机名 hostnamectl set-hostname minio1 hostnamectl set-hostname minio2 hostna…

【深度学习】训练过程中一个OOM的问题,太难查了

现象&#xff1a; 各位大佬又遇到过ubuntu的这个问题么&#xff1f; 现象是在训练过程中&#xff0c;ssh 上不去了&#xff0c;能ping通&#xff0c;没死机&#xff0c;但是ubunutu 的pc侧的显示器&#xff0c;鼠标啥都不好用了。只能重启。 问题原因&#xff1a; OOM了95G&a…