嵌入式初学-C语言-数据结构--四

news2024/9/25 1:19:14

1. 基本概念

栈是一种逻辑结构,是特殊的线性表。特殊在:

        只能在固定的一端操作

只要满足上述条件,那么这种特殊的线性表就会呈现一种“后进先出”的逻辑,这种逻辑就被称为栈。栈 在生活中到处可见,比如堆叠的盘子、电梯中的人们、嵌套函数的参数等等。

由于约定了只能在线性表固定的一端进行操作,于是给栈这种特殊的线性表的“插入”、“删除”,另起了 下面这些特定的名称:

        栈顶:可以进行插入删除的一端

        栈底:栈顶的对端

        入栈:将节点插入栈顶之上,也称为压栈,函数名通常为push()

        出栈:将节点从栈顶剔除,也称为弹栈,函数名通常为pop()

        取栈顶:取得栈顶元素,但不出栈,函数名通常为top()

基于这种固定一端操作的简单约定,栈获得了“后进先出”的基本特性,如下图所示,最后一个放入的元 素,最先被拿出来:

2. 存储形式

栈只是一种数据逻辑,如何将数据存储于内存则是另一回事。一般而言,可以采用顺序存储形成顺序 栈,或采用链式存储形成链式栈。

        顺序栈 顺序存储意味着开辟一块连续的内存来存储数据节点,一般而言,管理栈数据除了需要一块连续的 内存之外,还需要记录栈的总容量、当前栈的元素个数、当前栈顶元素位置,如果有多线程还需要 配互斥锁和信号量等信息,为了便于管理,通常将这些信息统一于在一个管理结构体之中:

// 顺序栈节点
struct seqStack
{
datatype *data; // 顺序栈入口
int size; // 顺序栈总容量
int top; // 顺序栈栈顶元素下标
};

链式栈

链式栈的组织形式与链表无异,只不过插入删除被约束在固定的一端。为了便于操作,通常也会创 建所谓管理结构体,用来存储栈顶指针、栈元素个数等信息:

// 链式栈节点
typedef struct node
{
datatype data;
struct node *next;
}node;
// 链式栈管理结构体
struct linkStack
{
node *top; // 链式栈栈顶指针
int size; // 链式栈当前元素个数
};

3. 基本操作 

不管是顺序栈,链式栈,栈的操作逻辑都是一样的,但由于存储形式不同,代码的实现是不同的。下 面分别将顺序栈和链式栈的基本核心操作罗列出来:

顺序栈

sstack.h
#ifndef __SSTACK_H
#define __SSTACK_H
// 数据类型
typedef int DATA;
// 顺序栈结构体
typedef struct
{
DATA *pData; // 栈中元素的地址
int size; // 栈的总容量
int top; // 栈顶元素下标
}SeqStack;
// 初始化栈
int SStack_init(SeqStack *s, int num);
// 判断栈是否已满
int SStack_isfull(SeqStack *st);
// 判断栈是否为空
int SStack_isempty(SeqStack *st);
// 入栈/压栈
int SStack_push(SeqStack *st,DATA data);
// 出栈/弹栈
int SStack_pop(SeqStack *st,DATA *data);
// 回收栈
int SStack_free(SeqStack *st);
#endif
sstack.c
#include <stdlib.h>
#include "sstack.h"
// 初始化栈
int SStack_init(SeqStack* s,int num)
{
s -> pData = (DATA*)calloc(sizeof(DATA),num);
if(s -> pData == NULL)
return -1;
s -> size = num ;
s -> top = -1;
return 0;
}
// 判断栈是否已满
int SStack_isfull(SeqStack *st)
{
return st -> top + 1 == st -> size;
}
// 判断栈是否为空
int SStack_isempty(SeqStack *st)
{
return st -> top == -1;
}
// 压栈/入栈
int SStack_push(SeqStack *st,DATA data)
{
if(SStack_isfull(st))
return -1;
st -> top++;
st -> pData[st -> top] = data;
return 0;
}
// 出栈/弹栈
int SStack_pop(SeqStack *st,DATA *data)
{
if(SStack_isempty(st))
return -1;
*data = st -> pData[st -> top];
st -> top--;
return 0;
}
// 回收栈
int SStack_free(SeqStack *st)
{
if(st -> pData)
{
free(st->pData);
st -> pData = NULL;
}
st -> top = -1;
}
sstack_main.c
#include "sstack.h"
#include <stdio.h>
int main(void)
{
SeqStack st;
SStack_init(&st,10);
register int i = 1;
for(; i <=10; i++)
SStack_push(&st,i);
if(-1 == SStack_push(&st,1024))
fprintf(stderr,"满栈,插入失败\n");
while(!SStack_isempty(&st))
{
DATA data = 0;
SStack_pop(&st,&data);
printf("%4d",data);
}
printf("\n");
SStack_free(&st);
return 0;
}

链式栈

inkstack.h
#ifndef __LINKSTACK_H
#define __LINKSTACK_H
// 数据类型
typedef int DATA;
// 链式栈节点
typedef struct _node
{
DATA data; // 数据
struct _node *next; // 指向下一个栈的节点
}NODE;
// 链式栈管理结构体
typedef struct
{
NODE *pHead;// 链式栈栈顶指针
int size; // 链式栈当前元素个数
int num;
}LinkStack;
// 初始化链式栈
int LStack_init(LinkStack *s, int num);
// 判断栈是否已满
int LStack_isfull(LinkStack *st);
// 判断栈是否为空
int LStack_isempty(LinkStack *st);
// 压栈/入栈
int LStack_push(LinkStack *st,DATA data);
// 弹栈/出栈
int LStack_pop(LinkStack *st,DATA *data);
// 回收栈
int LStack_free(LinkStack *st);
#endif
linkstack.c
#include "linkstack.h"
#include <stdio.h>
#include <stdlib.h>
// 初始化栈
int LStack_init(LinkStack *st, int num)
{
st -> pHead = NULL;
st -> size = num;
st -> num = 0;
return 0 ;
}
// 判断栈是否已满
int LStack_isfull(LinkStack *st)
{
return st -> num == st -> size;
}
// 判断栈是否为空
int LStack_isempty(LinkStack *st)
{
return st -> num == 0;
}
// 入栈
int LStack_push(LinkStack *st,DATA data)
{
if(LStack_isfull(st))
return -1;
NODE* p = (NODE*)malloc(sizeof(NODE));
if(!p)
return -1;
p -> data = data;
p -> next = st -> pHead;
st -> pHead = p;
(st -> num)++;
return 0;
}
// 出栈
int LStack_pop(LinkStack *st,DATA *data)
{
if(LStack_isempty(st))
return -1;
NODE* p = st -> pHead;
if(!p)
return -1;
*data = p -> data;
st -> pHead = p -> next;
free(p);
(st -> num)--;
return 0;
}
// 回收栈
int LStack_free(LinkStack *st)
{
NODE* p = st -> pHead, *q = NULL;
while(p)
{
q = p;
p = p -> next;
free(q);
}
st -> pHead = NULL;
st -> num = 0;
return 0;
}
linkstack_main.c
#include "linkstack.h"
#include <stdio.h>
int main(void)
{
LinkStack st;
LStack_init(&st,10);
register int i = 1;
for(; i <= 10; i++)
LStack_push(&st,i);
if(-1 == LStack_push(&st,1024))
fprintf(stderr,"满栈,插入失败\n");
while(!LStack_isempty(&st))
{
DATA data = 0;
LStack_pop(&st,&data);
printf("%4d",data);
}
printf("\n");
LStack_free(&st);
return 0;
}

使用链式栈,实现十进制转八进制:键盘输入一个十进制数,经过链式栈的相关算法,输出八进制 数。

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

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

相关文章

蓝牙串口模块JDY-31(基于STM32F103C8T6HAL库)

1.蓝牙模块简介 1.1 蓝牙模块简介 蓝牙串口模块用于单片机和手机之间的通信&#xff0c; JDY-31有6针脚和4针脚版本&#xff0c;6针脚插中间4根即可。 JDY-31是一个从机&#xff0c;HC-05是主从机一体的。HC-05使用的时候需要进行配对&#xff0c;JDY-31使用的时候不需要配对…

千万补贴计划,“健康中国行,陪诊惠民工程——陪诊志愿服务”全面开展

为了全面落实党的二十大报告关于“提高全社会文明程度&#xff0c;完善志愿服务制度和工作体系”和对志愿服务的一系列指示&#xff1a;“志愿服务是社会文明进步的重要标志&#xff0c;是广大志愿者奉献爱心的重要渠道”&#xff0c;“要为志愿服务搭建更多平台&#xff0c;更…

快速掌握AI算法基础:对于AI行业的“共同语言”入门指南

对于非相关专业的AI产品或者想要转型AI产品的同学&#xff0c;算法知识晦涩难懂&#xff0c;如何用很短的时间快速入门&#xff0c;让你在AI领域更加游刃有余。 一、机器学习、深度学习、强化学习的定义 1、机器学习&#xff08;Machine Learning, ML&#xff09; 机器学习是…

99%的Java程序员不知道的Java Instrument

Java Instrumentation API 是一个强大的工具&#xff0c;它允许开发人员在运行时修改字节码&#xff0c;而无需重新编译或修改源代码。这对于性能监控、日志记录、安全审计等场景非常有用。本文将深入探讨Java Instrumentation的基础知识&#xff0c;并通过具体的代码示例来展示…

【全网最全】2024年数学建模国赛C题超详细保奖思路+可视化图表+成品论文+matlab/python代码等(后续会更新

您的点赞收藏是我继续更新的最大动力&#xff01; 一定要点击如下的卡片&#xff0c;那是获取资料的入口&#xff01; 基于优化模型的农作物的种植策略 摘要 随着农业生产向集约化和智能化方向发展&#xff0c;优化种植策略以最大化经济收益成为当前农业研究中的重要问题。本…

828华为云征文|部署个人博客管理系统 Ghost

828华为云征文&#xff5c;部署个人博客管理系统 Ghost 一、Flexus云服务器X实例介绍1.1 云服务器介绍1.2 应用场景1.3 对比普通ECS 二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 Ghost3.1 Ghost 介绍3.2 Docker 环境搭建3.3 Ghost 部署3.4 …

记一次mysql锁等待超时问题

背景 如图所示&#xff0c;一个简单的删除语句&#xff0c;抛出了Lock wait timeout exceeded; try restarting transaction异常&#xff0c;查询这条记录&#xff0c;并尝试修改这条记录&#xff0c;发现修改操作都被hang住了 原因 待补充 解决方法 在mysql里&#xff0c…

营养三餐轻松搭配:健康生活从早餐开始

在如今的快节奏生活中&#xff0c;健康饮食与快捷管用的减调计划&#xff0c;已成为了许多人关注的焦点。合理的三餐搭配不仅能帮助我们控制形体&#xff0c;还能提升生活质量。今天&#xff0c;就让我们一起来学习一套科学的三餐减调套餐&#xff0c;让你在享受美食的同时&…

tuya open-sdk 1.0.0 发布

我们很高兴地宣布本次更新&#xff0c;带来了多项改进和新功能&#xff0c;旨在提升开发体验和效率。以下是具体更新内容&#xff1a; 代码标准化&#xff1a;实现了代码库的格式统一&#xff0c;引入了 clang-format 和 pre-commit 工具进行自动化代码格式调整&#xff0c;确保…

Docker 配置国内镜像源

由于 GFW 的原因&#xff0c;在下载镜像的时候&#xff0c;经常会出现下载失败的情况&#xff0c;此时就可以使用国内的镜像源。 什么是镜像源&#xff1a;简单来说就是某个组织&#xff08;学校、公司、甚至是个人&#xff09;先通过某种手段将国外的镜像下载下来&#xff0c;…

AI时代来临,AI基础数据服务行业未来发展有哪些变化

AI基础数据服务是针对人工智能&#xff08;AI&#xff09;领域提供的一项服务&#xff0c;它包括数据采集、数据清洗、信息抽取和数据标注等服务。AI基础数据服务旨在为AI算法的训练和优化提供必要的数据支持&#xff0c;为AI算法的性能提供保障。 标贝科技提供专业的数据采集、…

前端自查【知识点】(高概率)2024最新版

HTML 如何理解 HTML 语义化 ? 仅通过标签便能判断内容的类型&#xff0c;特别是区分标题、段落、图片和表格 增加代码可读性&#xff08;让人更容易读懂&#xff09;对SEO更加友好 &#xff08;让搜索引擎更容易读懂&#xff09; HTML有哪些内联元素和块状元素 ? 内联元素…

拌合站智能管理系统,如何实现智能化生产管理?

随着基础设施建设的不断推进&#xff0c;拌合站作为混凝土生产的重要环节&#xff0c;其管理水平直接影响到工程质量和施工效率。然而&#xff0c;传统的拌合站管理方法存在一些问题&#xff0c;如生产效率低、质量控制难、资源浪费等。在信息化和智能化技术迅猛发展的今天&…

4个工具帮你轻松实现视频在线压缩。

视频已经成了大家生活中很重要的一部分&#xff0c;能够帮助我们记录很多重要的东西&#xff0c;哟其实视频内容创作者&#xff0c;各种素材特别多。可使&#xff0c;随着视频越拍越多&#xff0c;设备的空间也会越来越紧张。所以&#xff0c;这次要为大家推荐4个专业的视频在线…

天翼云,AI取经路上的逐梦人

最近&#xff0c;国产第一部3A游戏大作《黑神话&#xff1a;悟空》问世&#xff0c;引发了全网热潮。游戏中的主角&#xff0c;重走西游之路&#xff0c;克服重重难关&#xff0c;向世界展现了中国文化的绝美与中国科技的自信。 而在现实当中&#xff0c;通往产业智能化的AI之路…

JVM系列(八) -运行期的几种优化技术

一、摘要 在之前的文章中我们谈到过,相比 C/C++ 语言,Java 语言在运行效率方面要稍逊一些,因为 Java 应用程序是在虚拟机上运行,而 C/C++ 程序是直接编译成平台相应的机器码来运行程序。 从虚拟机对外发布开始,开发团队一直在努力试图缩小 Java 与 C/C++ 语言在运行效率…

去除视频水印字幕从未如此简单!4款神器助你轻松搞定!

文章介绍的四款工具都已经打包好了,文末关注公众号AIshape 回复 “视频去水印” 获取 我们平时在各大视频网站下载的视频一般都会带有平台的logo水印,像Runway、Pika、即梦、可灵等AI视频生成平台创作的视频素材,非会员下载会带有水印 想利用这些视频素材进行二次创作很不方…

glsl着色器学习 (十二)平移

平移和旋转、缩放是一样的&#xff0c;替换成平移矩阵即可&#xff1b; // 创建一个单位矩阵 const translateYMatrix mat4.create();// 沿着Y轴向下平移1个单位 mat4.fromTranslation(translateYMatrix, [0, -1, 0]);// 设置矩阵 gl.uniformMatrix4fv(matrixUniformLocation…

Maven学习与使用

内容概要 Maven是什么&#xff0c;有什么作用会配置Maven的环境&#xff0c;以及在idea上配置&#xff08;重点&#xff09;掌握Maven的工程结构掌握Maven的几个重要指令。&#xff08;clean compile package install&#xff09;掌握如何导包及依赖冲突解决办法 1 Maven 1.…

超详细!!!最新的VuePress + Github Pages + Github Actions实现博客自动部署

超详细&#xff01;&#xff01;&#xff01;VuePress Github Pages Github Actions实现博客自动部署 本文着重讲述如何使用通过Github Actions将VuePress项目部署自动在Github Pages上。每一位开发者有一个自己的博客网站是一件很酷的事情&#xff0c;由于最近想整理一下在…