嵌入式学习-线性表Day03-栈

news2024/11/19 18:32:06

嵌入式学习-线性表Day03-栈

顺序栈

2)入栈

3)出栈

链式栈

什么是栈?

只能在一端进行插入和删除操作的线性表(又称为堆栈),进行插入和删除操作的一端称为栈顶,另一端称为栈底

栈特点

先进后出 FILO first in last out FILO

顺序栈

1)逻辑结构:线性结构

2)存储结构:顺序存储

3)操作:入栈、出栈

typedef struct seqstack

{

int * data;

int maxlen;

int top;

}seqstack_t;

1)创建一个空的栈

2)入栈

判满

移动栈针

将数据入栈

3)出栈

判空

移动栈针

将数据出栈

#ifndef _SEQSTACK_H_
#define _SEQSTACK_H_

typedef struct seqstack
{
	int* data;//指向栈的存储位置
	int maxlen;//保存栈的最大长度
	int top;//称为栈针,用的时候,心里面可以将按照顺序表里的last来使用
			//top 始终代表当前栈内最后一个有效元素的下标
}seqstack_t;
//1.创建一个空的栈
seqstack_t *CreateEpSeqStack(int len);//len代表的是创建栈的时候的最大长度
//2.判断是否为满,满返回1 未满返回0
int	 IsFullSeqStack(seqstack_t *p);
//3.入栈 
int  PushStack(seqstack_t *p, int data);//data代表入栈的数据
//4.判断栈是否为空
int IsEpSeqStack(seqstack_t *p);
//5.出栈 
int PopSeqStack(seqstack_t *p);
//6. 清空栈 
void ClearSeqStack(seqstack_t *p);
//7. 获取栈顶数据(注意不是出栈操作,如果出栈,相当于删除了栈顶数据,只是将栈顶的数据获取到,不需要移动栈针)
int GetTopSeqStack(seqstack_t *p);
//8. 求栈的长度
int LengthSeqStack(seqstack_t *p);
			#endif 

链式栈

逻辑结构:线性结构

存储结构:链式存储

操作:入栈出栈

#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_

//入栈和出栈只在第一个节点位置操作
typedef int datatype;
typedef struct linkstack
{
	datatype data;//数据域
	struct linkstack *next;//指针域
}linkstack_t;
//1.创建一个空的栈
void CreateEpLinkStack(linkstack_t **ptop);
//2.入栈   data是入栈的数据
参数上之所以采用二级指针,因为我们要随着入栈添加新的节点作为头,top需要永远指向当前链表的头,
那么修改main函数中的top,我们采用地址传递
int PushLinkStack(linkstack_t **ptop, datatype data);
//3.判断栈是否为空
int IsEpLinkStack(linkstack_t *top);
//4.出栈
datatype PopLinkStack(linkstack_t **ptop);
//5.清空栈
void ClearLinkStack(linkstack_t **ptop);//用二级指针,是因为清空后需要将main函数中的top变为NULL
//6.求栈的长度
int LengthLinkStack(linkstack_t *top);//用一级指针,是因为我只是求长度,不需要修改main函数中top指针的指向
//7.获取栈顶数据,不是出栈,不需要移动main函数中的top,所以用一级指针
datatype GetTopLinkStack(linkstack_t *top);
#endif

linkstack.c

#include<stdio.h>
#include<stdlib.h>

//入栈和出栈只在第一个节点位置操作
typedef int datatype;
typedef struct linkstack
{
	datatype data;//数据域
	struct linkstack *next;//指针域
}linkstack_t;
//1.创建一个空的栈
void CreateEpLinkStack(linkstack_t **ptop)//*ptop == top
{
    *ptop = NULL;
}
//2.入栈   data是入栈的数据
// 参数上之所以采用二级指针,因为我们要随着入栈添加新的节点作为头,top需要永远指向当前链表的头,
// 那么修改main函数中的top,我们采用地址传递
int PushLinkStack(linkstack_t **ptop, datatype data)
{
    //1.开辟空间存数据并初始化
    linkstack_t * pnew = (linkstack_t *)malloc(sizeof(linkstack_t));
    if(pnew == NULL)
    {
        perror("PushLinkStack err");
        return -1;
    }
    pnew->data = data;
    pnew->next = NULL;
    //2.将新节点插入无头单向链表中作为第一个节点
    pnew->next = *ptop;
    //3.移动栈针
    *ptop = pnew;
    return 0;
}
//3.判断栈是否为空
int IsEpLinkStack(linkstack_t *top)
{
    return top == NULL;
}
//4.出栈
datatype PopLinkStack(linkstack_t **ptop)
{
    //0.容错判断,判空
    if(IsEpLinkStack(*ptop))
    {
        perror("PopLinkStack err");
        return -1;
    }
    //1.定义pdel指向被删除节点
    linkstack_t *pdel = *ptop;
    //2.定义一个变量temp保存出栈数据
    datatype temp = pdel->data;
    //3.移动栈针
    *ptop = pdel->next;
    //4.释放被删除节点
    free(pdel);
    pdel =NULL;
    //5.返回数据
    return temp;
}
//5.清空栈
void ClearLinkStack(linkstack_t **ptop)//用二级指针,是因为清空后需要将main函数中的top变为NULL
{
    //只要不为空就出栈
    while (!IsEpLinkStack(*ptop))
        PopLinkStack(ptop);
    
}
//6.求栈的长度
int LengthLinkStack(linkstack_t *top)//用一级指针,是因为我只是求长度,不需要修改main函数中top指针的指向
{
    //遍历无头单向链表,求长度
    int len = 0;
    while (top != NULL)
    {
        len++;
        top=top->next;
    }
    return len;
}
//7.获取栈顶数据,不是出栈,不需要移动main函数中的top,所以用一级指针
datatype GetTopLinkStack(linkstack_t *top)
{
    // 只要不为空就返回数据
    if(!IsEpLinkStack(top))
        return top->data;
    return -1;
}
int main(int argc, char const *argv[])
{
    // linkstack_t *top = NULL;
    linkstack_t *top;
    CreateEpLinkStack(&top);
    for(int i=1;i<=5;i++)
        PushLinkStack(&top,i);
    printf("top value is %d\n",GetTopLinkStack(top));//5
    printf("len is %d \n",LengthLinkStack(top));//5
    while (!IsEpLinkStack(top))
        printf("%d ",PopLinkStack(&top));//5 4 3 2 1
    printf("\n");

    return 0;
}


总结:

顺序栈和链式栈的区别是什么?

1.存储结构不同,顺序栈相当于数组,连续的,链式栈 链表非连续的

2.顺序栈的长度受限制,而链栈不会

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

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

相关文章

儿童(青少年)可以参加哪些含金量高的比赛?

随着素质教育的推进&#xff0c;越来越多的家长和老师开始关注如何培养孩子的综合素质和能力。而参加各类比赛&#xff0c;不仅可以锻炼孩子的思维、动手能力和团队合作精神&#xff0c;还能帮助孩子在学习的过程中找到兴趣点和成就感。尤其是一些含金量高的比赛&#xff0c;不…

什么是静态加载-前端

什么是前端静态加载 在前端开发中&#xff0c;静态加载是一种常见且重要的技术。简单来说&#xff0c;前端静态加载指的是在页面加载时将所需的资源&#xff08;如HTML、CSS、JavaScript、图片等&#xff09;一并加载到用户的浏览器中。这种方式有助于提高页面的加载速度和用户…

【宽搜】6. leetcode 513 找树左下角的值

1 题目描述 题目链接&#xff1a;找树左下角的值 2 题目解析 思路&#xff1a; 可以使用 层序遍历&#xff0c; 将每一层的值都存入到一个vector< int> 中&#xff0c;当这一层是最后一层的时候&#xff0c;将vector< int>中的第一个值返回即可。 3 代码 cla…

RemoteView(kotlin)

使用场景&#xff1a;通知栏&桌面部件 自定义通知栏 通知权限申请 manifest配置 <uses-permission android:name"android.permission.POST_NOTIFICATIONS" />权限动态申请 package com.example.kotlinlearn.Common;import android.Manifest; import an…

国产长芯微LDUM8801光耦兼容的单通道隔离式栅极驱动器P2P替代UCC23513 FOD8342 TLP5751成本低,质量更好

描述 LDUM8801是单通道兼容光耦输入的隔离式栅极驱动器&#xff0c;可应用于驱动IGBT、SiC 和 MOSFET。它可以提供5A的峰值拉/灌电流。支持150kV/μs的最小共模瞬态免疫&#xff08;CMTI&#xff09;&#xff0c;确保了系统的鲁棒性。驱动器的最大电源电压为32V。 其与光耦式栅…

【计网】【计网】从零开始学习http协议 ---理解http重定向和请求方法

去光荣地受伤&#xff0c; 去勇敢地痊愈自己。 --- 简嫃 《水问》--- 从零开始学习http协议 1 知识回顾2 认识网络重定向3 http请求方法3.1 http常见请求方法3.2 postman工具进行请求3.3 处理GET和POST参数 1 知识回顾 前面两篇文章中我们学习并实现了http协议下的请求与应…

【LeetCode】每日一题 2024_10_9 找到按位或最接近 K 的子数组(LogTrick、位运算)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;找到按位或最接近 K 的子数组 代码与解题思路 今天是 2100 的题目&#xff0c;难度略高&#xff0c;不在我的能力范围&#xff0c;推荐题解&#xff1a;两种方法&#xff1a;LogTrick/滑…

设计模式——门面模式 | 外观模式

哈喽&#xff0c;各位盆友们&#xff01;我是你们亲爱的学徒小z&#xff0c;今天给大家分享的文章是设计模式的——门面模式。 文章目录 定义通用类图1.通用结构2.优点3.缺点 使用场景注意事项1.一个子系统可以有多个门面2.门面不参与子系统内的业务逻辑 定义 定义&#xff1a;…

【Flutter】合并多个流Stream

1.说明 无意间发现了一个好用的库rxdart&#xff0c;它为 Dart 的 Stream 添加了额外的功能。 2.功能 &#xff08;1&#xff09;合并多个流Stream 借助Rx.combineLatest2()合并两个流stream1和stream2。 注意&#xff1a;如果dart文件中同时使用了getx&#xff0c;需要隐…

PCL 3D-SIFT关键点检测(Z方向梯度约束

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 SIFT关键点检测 2.1.2 可视化函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff08;长期更新&#…

调用CString::Format接口格式化字符串时产生异常,可能是将当前的CString对象作为参数传给CString::Format接口导致的

最近有人在技术群里问一个关于使用MFC库中的CString类格式化字符串时遇到的问题&#xff0c;有时格式化出来的字符串有问题&#xff08;不是预期的&#xff09;&#xff0c;有时会产生异常崩溃&#xff0c;让我们帮忙分析一下&#xff0c;看看是什么原因导致的。 后来到MSDN上查…

JAVA基础: synchronized 和 lock的区别、synchronized锁机制与升级

1 synchronized 和 lock的区别 synchronized是一个关键字&#xff0c; lock是一个接口&#xff0c;实际使用的是实现类 synchronized通过触发的是系统级别的锁机制&#xff0c; lock是API级别的锁机制 synchronized自动获得锁&#xff0c;自动释放锁。 lock需要通过方法获得锁…

基于SSM的校园教务系统的设计与实现(论文+源码)_kaic

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对校园教务信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差…

【含开题报告+文档+PPT+源码】基于SSM框架的民宿酒店预定系统的设计与实现

开题报告 随着人们旅游需求的增加&#xff0c;民宿行业呈现出快速发展的趋势。传统的住宿方式逐渐无法满足人们对个性化、舒适、便捷的需求&#xff0c;而民宿作为一种新型的住宿选择&#xff0c;逐渐受到人们的青睐。民宿的特点是具有独特的风格、便捷的地理位置、相对亲近的…

基于yolov8的版面分析AI能力生产全流程

目录 1.coco数据集 1.1 基本定义 1.2应用场景 1.3 数据结构 2.labelme标注工具 2.1 基本定义 2.2 应用场景 2.3 安装步骤 3. 模型训练 3.1 数据标注 3.2 环境准备 3.3 数据预处理 3.4 模型训练 3.5 模型推理 4.参考链接 1.coco数据集 1.1 基本定…

数据库的相关知识

数据库的相关知识 1.数据库能够做什么&#xff1f; 存储大量数据&#xff0c;方便检索和访问保持数据信息的一致、完整共享和安全通过组合分析&#xff0c;产生新的有用信息 2.数据库作用&#xff1f; 存储数据、检索数据、生成新的数据 3.数据库要求&#xff1f; 统一、…

51单片机的自动洗手器【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机红外传感器继电器LED等模块构成。适用于红外感应洗手器、自动出水等相似项目。 可实现功能: 1、红外传感器实时采集人体信息&#xff0c;如果有人靠近&#xff0c;则闭合水泵继电器开始出水&#xff0c;人离开5s后&#xff0c;继电…

微信5大隐藏技巧,让你成为聊天高手

微信&#xff0c;这个几乎人人都在使用的应用&#xff0c;它的一些隐藏功能却鲜为人知。 今天&#xff0c;就让我们一起来探索这些实用的小技巧&#xff0c;让你的微信使用体验更上一层楼。 一键长截图&#xff0c;保存完整信息 在微信里&#xff0c;当你需要截取某个网页或公…

JAVA八股文1

1.Java 基础 1.1 语法基础 封装 利用抽象数据类型将数据和基于数据的操作封装在一起&#xff0c;使其构成一个不可分割的独立实体。数据被保护在抽象数据类型的内部&#xff0c;尽可能地隐藏内部的细节&#xff0c;只保留一些对外接口使之与外部发生联系。用户无需知道对象内…

【算法】链表:2.两数相加(medium)+模拟

系列专栏 《分治》 《模拟》 《Linux》 目录 1、题目链接 2、题目介绍 3、解法 (模拟) 4、代码 1、题目链接 2. 两数相加 - 力扣&#xff08;LeetCode&#xff09; 2、题目介绍 3、解法 (模拟) 理解题目要求&#xff1a; 我们有两个链表&#xff0c;每个链表代表一个…