数据结构学习:栈(详细讲解)

🎁个人主页:我们的五年

🔍系列专栏:C语言基本概念 

🌷追光的人,终会万丈光芒

🎉欢迎大家点赞👍评论📝收藏⭐文章

目录

🚗1.对栈概念理解:

🚗2.选择哪种数据结构实现栈:

🎉数组:

🎉链表:

🚗3.栈的几个基本操作函数:

🎉1.栈的初始化:

🎉2.栈的销毁:

🎉3.栈的初始化:

🎉4.取栈顶元素:

🎉5.对栈判空,为空返回true,不为空返回false:

🎉6.销毁栈顶元素:

🎉7.获取栈里面的元素个数:


 前言:

本次让我们来学习栈,以及对前面学习的顺序表和链表进行一个比较。

喜欢的铁子可以支持一下!祝大家天天开心!

🚗1.对栈概念理解:

栈的特点:先进后出。

入栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶

出栈:栈的删除操作叫做出栈,出数据也在栈顶

栈是和顺序表很像,我觉得是一种特殊的顺序表。栈只允许从一端进行插入和删除(访问一次就等于一次删除,就是出栈),但是可以同时进行插入和删除操作,不一定要把全部的数据入栈以后,再进行出栈。

●现实生活中栈的模型:弹夹,先装进去的子弹后出来,后装进去的子弹先被打出来。

●但是,下面的图形象化,更好理解。

 上面的表示的就是栈只能从一边入,也只能从这一边出数据。但是我可以入一个就出一个。也可以入两个,然后出一个,然后在入栈。

🚗2.选择哪种数据结构实现栈:

我们知道,栈就是一种线性结构,但是前面我们学的线性结构有数组,链表。

🎉数组:

物理(内存)上连续,逻辑上也连续:

数组的顺序存储结构,采用一组连续的内存来存储数据。

数组的线性关系是在内存(物理)上的相邻关系来表示数组的逻辑关系,也就是说,数组的连续和线性依靠的是内存的连续和线性。

●数组内存是连续的,所以可以随机访问,读取效率很高。

●数组在进行插入时,在下表为i的位置之前插入数据,需要把[i,n-1]的数据往后面移动,才能进行插入数据。但是如果在尾部插入就不需要对数组进行移动。

●数组在开辟的时候就要确定大小,如果是动态内存,后面进行增容的时候,还要考虑后面的空间知否足够,如果不足够,还要找一块新的内存,把之前的数据进行拷贝。因为是确定了大小了的,所以有时候会浪费空间。

🎉链表:

物理(内存上不连续,逻辑上连续:

链表是链式存储结构,链表的内存(物理)不一定是连续的,但是逻辑上是连续的。也就是可以通过节点一找到节点二,节点二可以找到节点……

●因为上面这种链式结构,所以链表的读取效率低,要读取数据,要去遍历链表。

●链表只是逻辑连续,所以在进行插入删除时也更方便。不需要对数据进行移动,只需要把新的节点与原来的链表建立联系。

●链表定义的时候,没有确定大小,所以链表的增容也更方便。

根据以上数组和链表的区别,我们可以思考在实现栈的时候,那种数据结构更好,因为栈只能在一端插入删除数据,插入删除数据的时候,只是在尾部进行插入删除,就不要去移动数据位置,这样我们就选择数组实现栈。

🚗3.栈的几个基本操作函数:

和顺序表和链表一样,都是自定义的结构体类型,所以我们要去实现一下它的几个基本函数。比如:栈的初始化,栈的销毁,入栈,出栈……

🎉1.栈的初始化:

//栈的初始化
void StackInit(Stack* ptr)
{
    assert(ptr);
    ptr->a = NULL;
    ptr->capacity = ptr->top = 0;
}

❗️注意:

1.一开始我们把top置为0,也就是说,没有数据的时候,top=0,top和元素个数的大小是一样的。

2.top=0,下次我们要插入数据的时候,也是在下标为0的位置进行插入,所以这是top表示的是栈顶元素的下一位

3.如果我们一开始把top=-1,就表示当前栈顶元素的下标。插入一个元素以后,top=0,插入的数据下标也是0,所以这个时候的top表示栈顶元素的下标。

🎉2.栈的销毁:

//销毁栈
void StackDestroy(Stack* ptr)
{
    assert(ptr);
    free(ptr->a);
    ptr->a = NULL;
    ptr->capacity = ptr->top = 0;    //初始化时,top=0,表示指向栈顶的下一个元素
}

🎉3.栈的初始化:

//在栈顶插入元素
void StackPush(Stack* ptr, SLDataType x)
{
    assert(ptr);
    if (ptr->top == ptr->capacity)
    {
        int newcapacity = ptr->capacity == 0 ? 4 : ptr->capacity * 2;
        SLDataType* tmp = (SLDataType*)realloc(ptr->a, newcapacity*sizeof(SLDataType));
        if (tmp == NULL)
        {
            perror("realloc fail");
            return;
        }
        ptr->a = tmp;
        ptr->capacity = newcapacity;
    }
    ptr->a[ptr->top++] = x;
}

❗️注意:

1.因为我们在栈的初始化的时候,我们没有申请数组大小,所以我们在插入数据在进行判断是否数据已经存满的时候,我们要去考虑数据个数为0的情况。

🎉4.取栈顶元素:

//取栈顶元素
SLDataType StackTop(Stack* ptr)
{
    assert(ptr);
    assert(!StackEmpty(ptr));
    return ptr->a[ptr->top - 1];
}
 

🎉5.对栈判空,为空返回true,不为空返回false:

//栈判空
bool StackEmpty(Stack* ptr)
{
    assert(ptr);
    return ptr->top == 0;
}

🎉6.销毁栈顶元素:

//销毁栈顶元素
void StackPop(Stack* ptr)
{
    assert(ptr);
    assert(!StackEmpty(ptr));

    ptr->top--;
}
 

🎉7.获取栈里面的元素个数:

//获取栈里面元素个数
int StackSize(Stack* ptr)
{
    assert(ptr);

    return ptr->top;
}

说明:

上面有些函数只有一条语句,我们还写成函数的形式,看上去感觉没有必要。但是当我们把我们写的函数给别人用,别人只要调用这些函数就可以了,就不会出错。

比如:没有函数,让别人使用的时候,当别人要去栈顶的元素,别人就不知道到底是top指向栈顶元素的下标,还是top-1是栈顶元素的下标。因为top初始化为0时,top-1指向指向栈顶元素的下标,top初始化为-1时,top指向栈顶元素的下标。

🚗4.栈的总体代码:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>typedef int SLDataType;typedef struct Stack{SLDataType* a;int top;int capacity;
}Stack;//对栈进行初始化
void StackInit(Stack* ptr);//对栈进行销毁
void StackDestroy(Stack* ptr);//在栈顶插入元素
void StackPush(Stack* ptr, SLDataType x);//获取栈顶元素
SLDataType StackTop(Stack* ptr);//对栈进行判断,如果为空,返回true,否则返回false
bool StackEmpty(Stack* ptr);//获取栈里面的元素个数
int StackSize(Stack* ptr);void StackPop(Stack* ptr);//栈的初始化
void StackInit(Stack* ptr)
{assert(ptr);ptr->a = NULL;ptr->capacity = ptr->top = 0;
}//销毁栈
void StackDestroy(Stack* ptr)
{assert(ptr);free(ptr->a);ptr->a = NULL;ptr->capacity = ptr->top = 0;	//初始化时,top=0,表示指向栈顶的下一个元素
}//在栈顶插入元素
void StackPush(Stack* ptr, SLDataType x)
{assert(ptr);if (ptr->top == ptr->capacity){int newcapacity = ptr->capacity == 0 ? 4 : ptr->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ptr->a, newcapacity*sizeof(SLDataType));if (tmp == NULL){perror("realloc fail");return;}ptr->a = tmp;ptr->capacity = newcapacity;}ptr->a[ptr->top++] = x;
}//取栈顶元素
SLDataType StackTop(Stack* ptr)
{assert(ptr);assert(!StackEmpty(ptr));return ptr->a[ptr->top - 1];
}//栈判空
bool StackEmpty(Stack* ptr)
{assert(ptr);return ptr->top == 0;
}//销毁栈顶元素
void StackPop(Stack* ptr)
{assert(ptr);assert(!StackEmpty(ptr));ptr->top--;
}//获取栈里面元素个数
int StackSize(Stack* ptr)
{assert(ptr);return ptr->top;
}

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

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

相关文章

力扣刷题Day5——内涵动态规划讲解

题目1&#xff1a; 先来一道很简单的题目&#xff1a; 2697. 字典序最小回文串 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 为了得到字典序最小的回文字符串&#xff0c;对于回文串&#xff0c;就是需要左右的字符相等&#xff0c;而要最小的回文串&#xff…

从开发角度理解漏洞成因(03)

文章目录 JS前端验证 - 文件上传设计浏览器禁用JS&#xff0c;前端绕过文件上传漏洞验证漏洞 Ajax 登录验证&#xff0c;状态回显&#xff0c;状态码设计修改返回包绕过登录验证 通过Ajax 传递数据进行购物验证设计1此漏洞也可以修改状态码绕过 持续更新中… 文章中代码资源已上…

Codeforces Round 943 (Div. 3) A~G1

A.Maximize?&#xff08;枚举&#xff09; 题意&#xff1a; 给你一个整数 x x x。你的任务是找出任意一个整数 y y y ( 1 ≤ y < x ) (1\le y\lt x) (1≤y<x)&#xff0c;使得 gcd ⁡ ( x , y ) y \gcd(x,y)y gcd(x,y)y为最大可能数。 ( 1 ≤ y < x ) (1\le y\lt…

深入解析Python中的`add_argument`用法

深入解析Python中的add_argument用法 在Python编程中&#xff0c;add_argument通常与命令行参数解析库argparse有关。这个库主要用于编写用户友好的命令行接口&#xff0c;其核心功能之一就是通过add_argument方法来指定程序可以接受哪些命令行参数。本篇博客将详细介绍argpar…

【算法练级js+java】重复给定字符n次

题目 Repeats the given string n times.&#xff08;复制指定的字符串n次&#xff09; 期望结果 /** * Repeats the given string n times. * * repeat(‘, 3) * // > **’ * * repeat(‘abc’, 2) * // > ‘abcabc’ * * repeat(‘abc’, 0) * // > “” **/ 代码…

【自动驾驶|毫米波雷达】逻辑化讲清快时间与慢时间傅里叶变换

碎碎念&#xff1a;实习过程中发现在进行雷达知识交流时&#xff0c;大部分同事都会用英文简称代替中文的一些称呼&#xff0c;比如Chirp、FFT等等。起初我觉得是因为很多英伟达、TI芯片的开发教程都是英文的&#xff0c;所以看得多了大家都习惯这样称呼&#xff0c;后来在和指…

python爬虫学习------scrapy第三部分(第三十一天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

Sarcasm detection论文解析 |使用 BERT 进行中间任务迁移学习的刺检测

论文地址 论文地址&#xff1a;https://www.mdpi.com/2227-7390/10/5/844#/ github&#xff1a;edosavini/TransferBertSarcasm (github.com) 论文首页 笔记框架 使用 BERT 进行中间任务迁移学习的讽刺检测 &#x1f4c5;出版年份:2022 &#x1f4d6;出版期刊:Mathematics &…

如何利用AI提高内容生产效率

目录 一、自动化内容生成 二、内容分发与推广 三、内容分析与优化 图片来源网络&#xff0c;侵权联系可删 一、自动化内容生成 随着AI技术的飞速发展&#xff0c;自动化内容生成已经成为提高内容生产效率的重要手段。AI可以通过自然语言处理&#xff08;NLP&#xff09;、机…

参数服务器

参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器&#xff0c;可以将数据存储在该容器中&#xff0c;被不同的节点调用&#xff0c;当然不同的节点也可以往其中存储数据。 参数服务器&#xff0c;一般适用于存在数据共享…

鸿蒙内核源码分析(特殊进程篇)

三个进程 鸿蒙有三个特殊的进程&#xff0c;创建顺序如下: 2号进程&#xff0c;KProcess&#xff0c;为内核态根进程.启动过程中创建.0号进程&#xff0c;KIdle为内核态第二个进程&#xff0c;它是通过KProcess fork 而来的.这有点难理解.1号进程&#xff0c;init&#xff0c…

【2024最新华为OD-C卷试题汇总】游戏表演赛分队(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; 文章目录 前…

VS编辑器下使用MFC完成数据相册系统

背景&#xff1a; 实验项目8:数字相册系统 (2周) (一)实验目的 通过该实验&#xff0c;使学生掌握windows程序设计的基本方法。了解相册的基本功能&#xff0c;在传统相册的基础上&#xff0c; 通过应用时钟、图形绘制功能、图形文件的读写功能以及数据库技术&#xff0c;实现对…

AI模型:windows本地运行下载安装ollama运行Google CodeGemma可离线运行数据模型【自留记录】

AI模型&#xff1a;windows本地运行下载安装ollama运行Google CodeGemma可离线运行数据模型【自留记录】 CodeGemma 没法直接运行&#xff0c;需要中间软件。下载安装ollama后&#xff0c;使用ollama运行CodeGemma。 类似 前端本地需要安装 node.js 才可能跑vue、react项目 1…

人大金仓数据库报com.kingbase8.util.KSQLException: 致命错误: 用户 “SYSTEM“ Password 认证失败

com.kingbase8.util.KSQLException: 致命错误: 用户 “SYSTEM” Password 认证失败 解决办法&#xff1a; 问题在于用户权限只不足&#xff0c;相关配置文件在一般在 /data/sys hba.conf,修改IPV4 local connections选项中的改为trust。

网络机顶盒哪个牌子好?经销商整理热门网络机顶盒排名

做实体数码店多年来&#xff0c;网络机顶盒这行我非常了解&#xff0c;各种品牌的网络机顶盒我们全销售过。近来很多朋友咨询我网络机顶盒哪个牌子好&#xff0c;我按照店内近一个季度的销量情况整理了是实体店最畅销的网络机顶盒排名&#xff0c;最受欢迎的品牌是以下这些&…

时钟模块RX8025SA 内置32.768 kHz石英晶体振荡器

实时时钟模块RX8025SA&#xff0c;料号Q41802552000100&#xff0c;是一款低功耗&#xff0c;高精度时钟芯片。时钟芯片RX8025SA选型过程中应该注意哪些&#xff1f;RX8025SA又应用在哪些领域呢&#xff1f;爱普生RTC实时时钟RX8025SA&#xff0c;内置32.768 kHz石英晶体振荡器…

泰山众筹:创新电商模式引领共赢新时代

一、泰山众筹模式概述 泰山众筹模式&#xff0c;作为一种创新型的电商策略&#xff0c;巧妙地将产品销售与积分众筹相结合&#xff0c;为用户和平台双方创造了互利共赢的机会。在此模式下&#xff0c;用户购买指定产品即可获得相应积分&#xff0c;进而可将这些积分投入到众筹…

AI换脸原理(2)——人脸检测参考文献S3FD:源码解析

1 介绍 S3FD是一个实时人脸检测器,这篇论文的主要思想是试图解决一个常见的问题,即基于anchor(锚点)的检测器随着人脸变小而急剧恶化。 基于锚点的目标检测方法是通过对一系列预设锚点进行分类和回归来检测目标的,这些锚点是通过在图像上有规律地平铺一组不同尺度和宽高比…

怎么快速分享视频文件?用二维码看视频的方法

怎样不通过传输下载分享视频内容呢&#xff1f;以前分享视频内容&#xff0c;大多会通过微信、QQ、邮箱、网盘等形式来传递。但是这种方式需要下载后才可以观看&#xff0c;不仅占用手机内存&#xff0c;而且效率也比较低&#xff0c;所以现在很多人会采用视频生成二维码的方式…