数据结构与算法学习——栈结构

news2024/9/23 15:18:58

在程序设计中,一定接触过“堆栈”的概念。其实,“栈 ” 和 “堆 ” 是两个不同的概念。这里,栈是一种特殊的数据结构,在中断处理特别是重要数据的现场保护有着重要意义。

  1. 什么是栈结构

数据的逻辑结构来看,栈结构其实就是一种线性结构。如果从数据的存储结构来进一步划分,栈结构包括两类。

顺序桟结构:即使用一组地址连续的内存单元依次保存栈中的数据。在程序中,可以定义一个指定大小的结构数组来作为栈,序号为0的元素就是栈底,再定义一个变量top保存栈顶的序号即可。

链式栈结构:即使用链表形式保存栈中各元素的值。链表首部 (head 指针所指向元素)为栈顶 ,链表尾部 (指向地址为NULL) 为栈底。

典型的栈结构,如图1所示。从图中可以看出,在栈结构中只能在一端进行操作,该操作端称为栈顶,另一端称为栈底。也就是说,保存和取出数据都只能从栈结构的一端进行。从数据的运算角度来分析,栈结构是按照“后进先出”的原则处理结点数据的。
在这里插入图片描述

其实,栈结构在日常生活中有很多生动的例子。例如,当仓库中堆放货物时,先来的货物放在里面,后来的货物码放在外面;而要取出货物时,总是先取外面的,鉍后才能取到里面放的货物。也就是说,后放入货物先取出。

在栈结构中,只有桟顶元素是可以访问的,栈结构的数据运算也非常简单。一般栈结构的基本操作只有两个。

  • 入栈(Push):将数据保存到栈顶的操作。进行入栈操作前,先修改栈顶指针,使其向上移一个元素位置,然后将数据保存到栈顶指针所指的位置。
  • 出栈(Pop):将栈顶数据弹出的操作。通过修改找顶指针,使其指向栈中的下一个元素。
  1. 栈的数据结构定义
#include <stdio.h>
#include <malloc.h>
#define  MAXLEN  50 //定义栈结构的最大长度
typedef struct
{
   char  name[10];  //姓名
   int   age;      //年龄
}Data;
typedef struct stack
{
    Data  data[MAXLEN];  //数据元素
    int   top ;          
//栈顶   top为0时表示栈空,top为MAXLEN-1表示栈满。
}Student;
  1. 初始化栈结构
    在使用顺序栈之前,首先要创建一个空的顺序栈,也就是初始化顺序栈。顺序栈的初始化操作步骤如下:

(1)按符号常量MAXLEN指定的大小申请一片内存空间,用来保存栈中的数据。

(2) 设置栈顶指针的值为0 ,表示是一个空栈。

初始化顺序栈的示例代码如下:

Student  *StInit()
{
    Student  *p;
    if(p=(Student *)malloc(sizeof(Student)))
    {
        p->top = 0; //设置栈顶为0;
        return p;  //返回指向栈的指针
    }
    return NULL;
}

说明:首先使用malloc()函数申请内存,申请成功后设置栈顶为0,然后返回申请内存的首地址。如果申请内存失败,将返回—NULL。

  1. 判断空栈

判断空栈就是判断一个栈结构是否为空。如果是空栈,则表示该栈结构中没有数据。此时可以进行入栈操作,但不可以进行出找操作。

判断空栈代码如下

int StIsEmpty(Student *s)
{    
    int t;
    t = s->top==0?1:0;
 
    return t;
}

说明:在这里,输入参数s为一个指向操作的栈的指针。程序中,根据栈顶指针top是为0,判断栈是否为空。

  1. 判断满栈

判断满找就是判断一个栈结构是否为满。如果是满栈,则表示该找结构中没有多余的空间来保存额外数据。此时不可以进行入栈操作,但是可以进行出找操作。

判断满栈的示例代码如下:

int  StIsFull(Student *s)
{
    int t;
    t = s->top == MAXLEN - 1?1:0;
 
    return t;
}

说明:在这里,输入参数s为一个指向操作的栈的指针。程序中判断栈顶指针top是否已等于符号常量MAXLEN - 1,从而判断栈是否已满。

  1. 清空栈
    淸空栈就是栈中的所有数据被淸除。清空栈的示例代码如下:
void  StClear(Student *s)
{
    s->top == 0;
}

说明:在这里,输入参数s 为一个指向操作的栈的指针。程序中,简单地将栈顶指针top设置为0,表示执行清空栈操作。

  1. 释放空间
    释放空间是释放栈结构所占用的内存单元。由前面可知,在初始化栈结构时,使用了 malloc()函数分配内存空间。虽然可以使用清空栈操作,但是清空栈操作并没有释放内存空间,这就需要使用free()函数释放所分配的内存。

释放空间的示例代码如下

void StFree(Student *s)
{
    if(s)
      free(s);
}

说明:在这里,输入参数s为一个指向操作的栈的指针。程序中,直接调用free函数释放所分配的内存。一般在不需要使用栈结构时调用该函数,特别是程序结束时。

  1. 入栈
    入栈(Push)是栈结构的基本操作,主要操作是将数据元素保存到栈结构。入栈操作的具体步骤如下:

(1) 首先判断桟顶top,如 果top大于等于MAXLEN则表示溢出, 进行出错处理。否则执行以下操作。

(2) 设置top=top+1 (栈顶指针加1 , 指向入栈地址)。

(3)将入栈元素保存到top指向的位置。

入栈操作的示例代码如下:

int PushSt(Student *s, Data data)
{
    if(s->top >= MAXLEN)
    {
        printf("栈溢出!\n");
        return 0;
    }
    s->data[++s->top] = data;   //将元素入栈
 
    return 1;
}

说明:在这里,输入参数s为一个指向操作的栈的指针,输入参数data是需要入栈的数据元素。程序中首先判断栈是否溢出,如果溢出则不进行入栈操作,否则修改栈顶指针的值,再将元素入栈。

  1. 出栈

出栈(Pop)是栈结构的基本操作,主要操作与入栈相反,它是从栈顶弹出一个数据元素。出栈操作的具体步骤如下:

(1)首先判断栈顶top,如果top等于0,则表示为空栈,进行出错处理。否则,执行下面的步骤。

(2)将栈顶指针top所指位置的元素返回。

(3)设置top=top-1, 也就是使栈顶指针减1 , 指向栈的下一个元素,原来找顶元素被弹出。

Data PopSt(Student *s)
{
    if(s->top==0)
    {
        printf("栈为空!\n");
        exit(0);
    }
 
    return (s->data[s->top--]);
}

说明:在这里,输入参数s为一个指向操作的栈的指针。该函数返回值是一个Data类型的数据,返回值是栈顶的数据元素。

  1. 读结点数据

读结点数据也就是读取栈结构中结点的数据。由于找结构只能在一端进行操作,因此这里的读操作其实就是读栈顶的数据。

需要注意的是,读结点数据的操作和出栈操作不同。读结点数据的操作仅是显示栈顶结点数据的内容,而出找操作则将栈顶数据弹出,该数据不再存在。

Data PeekSt(Student *s)
{
     if(s->top==0)
    {
        printf("栈为空!\n");
        exit(0);
    }
 
    return (s->data[s->top]);
}
 

说明:在这里,输入参数s 为一个指向操作的栈的指针。该函数返回值同样是一个Data类型的数据,返回值是栈顶的数据元素。

  1. 完整实例
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
 
#define  MAXLEN  50 //定义栈结构的最大长度
 
typedef struct
{
   char  name[10];  //姓名
   int   age;      //年龄
}Data;
 
typedef struct stack
{
    Data  data[MAXLEN];  //数据元素
    int   top ;          //栈顶   top为0时表示栈空,top为MAXLEN-1表示栈满。
}Student;
 
 
//初始化顺序栈
Student  *StInit()
{
    Student  *p;
 
    if(p=(Student *)malloc(sizeof(Student)))
    {
        p->top = 0; //设置栈顶为0;
        return p;  //返回指向栈的指针
    }
 
    return NULL;
}
 
//判断空栈
int StIsEmpty(Student *s)
{    
    int t;
    t = s->top==0?1:0;
 
    return t;
}
 
//判断栈满
int  StIsFull(Student *s)
{
    int t;
    t = s->top == MAXLEN - 1?1:0;
 
    return t;
}
 
//清空栈
void  StClear(Student *s)
{
    s->top == 0;
}
 
//释放空间
void StFree(Student *s)
{
    if(s)
      free(s);
}
 
//入栈
int PushSt(Student *s, Data data)
{
    if(s->top >= MAXLEN)
    {
        printf("栈溢出!\n");
        return 0;
    }
    s->data[++s->top] = data;  //将元素入栈
 
    return 1;
}
 
//出栈
Data PopSt(Student *s)
{
    if(s->top==0)
    {
        printf("栈为空!\n");
        exit(0);
    }
 
    return (s->data[s->top--]);
}
 
//读栈顶数据
Data PeekSt(Student *s)
{
     if(s->top==0)
    {
        printf("栈为空!\n");
        exit(0);
    }
 
    return (s->data[s->top]);
}
 
int main(void)
{
    Student *s;
    Data d1,d2;
 
    s = StInit();
    printf("入栈操作:\n");
    printf("输入姓名  年龄进行入栈:\n");
 
    do{
        scanf("%s%d",d1.name,&d1.age);
        if(strcmp(d1.name,"0")==0)
            break;  //若输入0,则退出
        else
        {
            PushSt(s,d1);
        }
    }while(1);
    printf("\n");
    do{
        printf("出栈操作:按任意键进行出栈操作:\n");
        getchar();   //输入空格
        d2 = PopSt(s);
        printf("出栈数据是(%s, %d)\n",d2.name,d2.age);
    } while(1);   
 
    StFree(s);
 
    return 0;
 
}

说明:在这里主函数首先初始化栈结构,然后循环进行入栈操作,添加数据结点,当输入值全部为0 时则退出结点添加的进程。接下来,用户每按一次键,则进行一次出栈操作,显示结点数据 。当为空栈时,退出程序。

运行结果如下:
在这里插入图片描述

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

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

相关文章

59. 微调(fine-tuning)代码实现

1. 热狗识别 让我们通过具体案例演示微调&#xff1a;热狗识别。 我们将在一个小型数据集上微调ResNet模型。该模型已在ImageNet数据集上进行了预训练。 这个小型数据集包含数千张包含热狗和不包含热狗的图像&#xff0c;我们将使用微调模型来识别图像中是否包含热狗。 %matp…

专访中银金科:数字驱动成为新的增长引擎,未来业务转化是关键

大数据和信息科技正在逐步颠覆银行业过往的业务模式。建立以数据驱动为核心&#xff0c;以优化客户体验为目标的可持续营销理念&#xff0c;逐渐成为行业的共识。但是&#xff0c;伴随着银行业数字化转型进程加速发展&#xff0c;海量客户数据和低效营销之间的矛盾日益凸显。在…

Linux apt 命令

apt&#xff08;Advanced Packaging Tool&#xff09;是一个在 Debian 和 Ubuntu 中的 Shell 前端软件包管理器。 apt 命令提供了查找、安装、升级、删除某一个、一组甚至全部软件包的命令&#xff0c;而且命令简洁而又好记。 apt 命令执行需要超级管理员权限(root)。 apt 语…

23.2、Junit单元测试反射注解

Java代码执行的三个阶段 Junit单元测试&#xff1a; * 测试分类&#xff1a; 1. 黑盒测试&#xff1a;不需要写代码&#xff0c;给输入值&#xff0c;看程序是否能够输出期望的值。 2. 白盒测试&#xff1a;需要写代码的。关注程序具体的执行流程。 * Junit使用&#…

洛谷千题详解 | P1030 [NOIP2001 普及组] 求先序排列【C/C++、pascal语言】

博主主页&#xff1a;Yu仙笙 专栏地址&#xff1a;洛谷千题详解 目录 题目描述 输入格式 输出格式 输入输出样例 解析&#xff1a; C源码&#xff1a; C源码2&#xff1a; pascal源码&#xff1a; C源码&#xff1a; --------------------------------------------------------…

P4Pi AP转wifi模式

调试时间&#xff1a;2022.11.07 树莓派在安装P4Pi后&#xff0c;会自动设置为AP热点模式。本文档通过配置将树莓派系统从ap模式转变为wifi模式。 1 调试环境 Raspberry 4B 4GB-SDcard 32GB Raspberry Pi Imager v1.7.3 Raspberry Pi OS – Raspberry PiFrom industries lar…

值得信赖的数据同步备份软件 -Allway Sync 安全又可靠,简单又易用!

Allway Sync 是一款可靠的数据同步备份工具&#xff0c;最初的版本发布于 2004 年 4 月 19 号&#xff0c;距离今日大约有 19 年的更新历史了&#xff0c;足以说明软件绝对稳定&#xff0c;时间验证了软件的可靠性&#xff01;而对于我们用户来说&#xff0c;数据同步备份最重要…

基于线性表的查找

目录 一、查找的基本概念 二、顺序查找 关键代码 完整代码 运行结果 增加哨兵 三、二分查找&#xff08;折半查找&#xff09; 关键代码 完整代码 运行结果 四、分块查找 图示 关键代码 完整代码 一、查找的基本概念 对查找表进行的操作 1.查找某个特定的数据元素是否存在 …

攻防世界-fakebook

题目 访问题目场景 我自己尝试了很久&#xff0c;发现怎么都找不到这道题的入手点&#xff0c;然后就去看了大佬们的文章&#xff0c;然后我发现这道题更趋近于真实的场景 解题过程 先使用目录扫描器扫一下发现存在robots.txt访问一下 这里发现存在一个备份文件 <?php…

html、css、js的小米商城

首页的展示 首页的功能 1、搜索栏模糊查询 在我在输入框输入关键字的时候&#xff0c;会匹配关键字&#xff0c;如果我的存放的数据里面包含这些关机键字就会显示出来。做到模糊查询的效果。 2、实现搜索功能 在首页的搜索框点击搜索的时候&#xff0c;就会对你输入的关键字进…

Redis 未授权访问的原理、危害及复现

原理介绍 Redis 未授权访问 准确的来说&#xff0c;其实并不是一个漏洞。而是由于开发人员配置不当&#xff0c;而产生的预料之外的危害。 具体原理&#xff1a; 可能由于部分业务要求&#xff0c;或者开发人员的配置不当&#xff0c;将 redis 服务器的 ip 和 port 暴露在公网…

基础数学(7)——常微分方程数值解法

文章目录期末考核方式基础知识解析解&#xff08;公式法&#xff09;解析解例题&#xff08;使用公式法&#xff0c;必考&#xff09;解析解的局限性数值解数值解的基本流程显示Euler法显示欧拉&#xff08;差值理解&#xff09;显示欧拉&#xff08;Taylor展开理解&#xff09…

ClickHouse表引擎详解看这篇就够了-基本讲解、处理逻辑、测试实例

表引擎是ClickHouse设计实现中的一大特色。表引擎在 ClickHouse 中的作用十分关键&#xff0c;直接决定了数据如何存储和读取、是否支持并发读写、是否支持 index、支持的 query 种类、是否支持主备复制等。1、表引擎概述1.1 介绍ClickHouse 提供了大约 28 种表引擎&#xff0c…

ArcGIS基础实验操作100例--实验43填充面要素空洞

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验43 填充面要素空洞 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&a…

JavaScript 条件语句

文章目录JavaScript If...Else 语句条件语句If 语句If...else 语句If...else if...else 语句JavaScript If…Else 语句 条件语句用于基于不同的条件来执行不同的动作。 条件语句 通常在写代码时&#xff0c;您总是需要为不同的决定来执行不同的动作。您可以在代码中使用条件语…

【学习笔记】Shell入门

Shell入门 https://www.bilibili.com/video/BV1WY4y1H7d3 资料&#xff1a;评论区取的 公众号的资料链接 https://pan.baidu.com/s/1_nBKUjE57MB2c96wmfSD5A 提取码&#xff1a;yyds 文章目录一、**Shell** 概述二、**Shell** 脚本入门三、变量1.系统预定义变量2.自定义变量**3…

自学软件测试该如何入门?

互联网行业发展很快技术更新也很快&#xff0c;软件测试技能要求在逐渐提高&#xff0c;自学软件测试要尽快而且入行后需要持续学习。保持好心态&#xff0c;找准教程&#xff0c;按照学习路线和自己的规划一步步学习下去~ 软件测试对代码的要求不像其他编程学科那么高&#x…

30个精品Python练手项目

随着 Python 语言的流行&#xff0c;越来越多的人加入到了 Python 的大家庭中。到底为什么这么多人学 Python &#xff1f;我要喊出那句话了&#xff1a;“人生苦短&#xff0c;我用 Python&#xff01;”&#xff0c;正是因为语法简单、容易学习&#xff0c;所以 Python 深受大…

Java微服务连接云服务器上的ZooKeeper

前言 这次要讲的连接ZooKeeper是在外网的云服务器上&#xff0c;不同于以往的本机上的虚拟机上的ZooKeeper&#xff0c;将会有一些不同于本机的连接方式。连接外网服务器进行操作可以更好的适应企业化的开发&#xff0c;脱离了本机的限制&#xff0c;具有很强的实战意义。 前…

小程序容器产品有何特点?

小程序容器顾名思义&#xff0c;是一个承载小程序的运行环境&#xff0c;可主动干预并进行功能扩展&#xff0c;达到丰富能力、优化性能、提升体验的目的。目前市面已知的技术产品包括&#xff1a;mPaas、FinClip、uniSDK 以及上周微信团队才推出的 Donut。今天&#xff0c;我们…