数据结构 栈与队列详解!!

一.栈

 关于内存中的栈和数据结构中的栈是不同的,本章着重讲的是数据结构的栈。

 这是一张关于栈的表达图。从图中可以看出栈很像是一副卡牌,发牌时只能从上取出,即出栈。

而入栈则是像你出牌后,要把你出的牌压在上一张出的牌上面。这是入栈。

栈可以用链表或者顺序表实现,这里采用的是顺序表的结构。

1.栈的头文件 

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int StackDatatype;
typedef struct Stack
{StackDatatype* data;int capacity;int Top;
}ST;
void STPush(ST* pst, StackDatatype x);
void StackInit(ST* pst);
void StackDestroy(ST* pst);
void Push(ST* pst, StackDatatype x);
void Pop(ST* pst);
StackDatatype StackTop(ST* pst);
int StackSize(ST* pst);
bool StackEmpty(ST* pst);

 2.栈的初始化

void StackInit(ST* pst)
{assert(pst);pst->capacity = 0;pst->data = NULL;pst->Top = -1;
}

这里的pst->Top可以用-1,或者0.用-1的话后续你的pst->Top 所代表的下标就是栈顶元素。

如果用0 那pst-Top 之后的下标就是栈顶元素的下一个位置。这里可以自己考虑,代码的多样性。 (本章采用的是-1 的写法)

3.栈的插入

void Push(ST* pst, StackDatatype x)
{assert(pst);pst->Top++;JudgeCapacity(pst);pst->data[pst->Top] = x;
}

栈的插入就是入栈,top++ 是pst->top 指向当前即将插入元素的位置(栈顶的位置)。

后面在判断pst中的容量,不够需要扩容。把x 插入栈顶位置。 

4.栈的取出

void Pop(ST* pst)
{assert(pst);assert(pst->Top > -1);pst->Top--;
}

和顺序表一样只要 top--即可,不用删除,因为top -- 以后,你下次在使用该位置的时候,其实就是把原来这个位置的元素更改就可以了,不需要删除。

5.栈的栈顶元素

StackDatatype StackTop(ST* pst)
{assert(pst);return pst->data[pst->Top];
}

 这个函数的存在意义就是取当前的栈顶元素的值。

6.栈的元素个数

int StackSize(ST* pst)
{assert(pst);return pst->Top+1;
}

因为我们的Top 用的是-1开头,所以,当它指向第一个元素的时候,这时候Top == 0, 所以加一。

7.栈的判空

bool StackEmpty(ST* pst)
{assert(pst);return pst->Top == -1;
}

判断栈此时是否为空,用pst- top == -1 的判断表达式返回即可。 

8.栈的销毁

void StackDestroy(ST* pst)
{assert(pst);free(pst->data);pst->data = NULL;pst->capacity = 0;pst->Top = -1;
}

因为栈是创建出来的一个空间。所以最后要将这段空间free,并将所有数据都置空 

栈的容量判断

void JudgeCapacity(ST* pst)
{assert(pst);if (pst->capacity == pst->Top){int newcapacity = pst->capacity == 0 ? 4 : 2 * pst->capacity;StackDatatype* tmp = (StackDatatype*)realloc(pst->data, sizeof(StackDatatype) * newcapacity);if (tmp == NULL){perror("malloc failed!");return;}pst->data = tmp;pst->capacity = newcapacity;}
}

 和顺序表的容量判断一样,有兴趣的可以直接去看我的顺序表详解,这里给大家简单的说一下,用三目表达式判断并赋值newcapacity,然后扩容pst->data这一段空间。

最后把扩容好的空间地址给到tmp,newcapacity给到原来的capacity。

二.队列

 上图是队列的表达图,队列如字意就像是排队一样,先进入的人,就先获得服务。

所以 队列和 栈的不同点就是出栈和出队,队列出的是头元素,而栈出的是尾元素(栈顶)

对比入队和 入栈两者相似都是尾插。

,还有队列用的是链表,栈用的是顺序表。

1.队列的头文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int QeDataType;
typedef struct QueueNode
{struct QueueNode* next;QeDataType data;
}Qnode;
typedef struct Queue
{Qnode* head;Qnode* back;
}Qe;
void QueueInit(Qe* q);
void QueueDestroy(Qe* q);
void Queuepush(Qe* q, QeDataType x);
void QueuePop(Qe* q);
QeDataType QueueFront(Qe* q);
QeDataType QueueBack(Qe* q);
int QueueSize(Qe* q);
bool QueueEmpty(Qe* q);

 相比栈 队列多用了一个typedef 原因是,队列要记录头元素和尾元素。因为入队入的在尾部,出队出的是头部

2.队列的初始化

void QueueInit(Qe* q)
{assert(q);Qnode* newnode = CreateNode(-1);q->head = newnode;q->back = newnode;
}

 这里采用的是有头结点的队列,当然没有头结点(哨兵位)也是可以的,根据个人喜好选择。

初始化创立一个头结点(哨兵位)后,头指针和尾指针都指向头结点(哨兵位)

3.队列的插入

void Queuepush(Qe* q, QeDataType x)
{assert(q);Qnode* newnode = CreateNode(x);q->back->next = newnode;q->back = newnode;
}

 关于队列的插入,就是链表的尾插,如果链表还没明白的朋友,可以去看我之前关于单链表的博客。

4.队列的取出

void QueuePop(Qe* q)
{assert(q);assert(q->head->next);Qnode* next = q->head->next;q->head->next = next->next;free(next);next = NULL;if (q->head->next == NULL){q->back = q->head;q->back->next = NULL;}
}

关于队列的取出,实质上就是链表的头删。 

5.队列的头元素

QeDataType QueueFront(Qe* q)
{assert(q);assert(q->head->next);return q->head->next->data;
}

 队列的头元素返回就是返回哨兵位后的第一个节点的数据。因为要返回数值,所以这个第一个节点不能为空,用assert断言。

6.队列的尾元素

QeDataType QueueBack(Qe* q)
{assert(q);assert(q->head->next);return q->back->data;
}

 既然要返回尾元素的数据,那就是用到尾指针,当然链表第一个节点不能为空。

7.队列的元素个数

int QueueSize(Qe* q)
{Qnode* size = q->head->next;int num = 0;while (size){size = size->next;num++;}return num;
}

队列的元素个数,就把链表遍历一遍,用num记录遍历次数,就是元素个数。 

8.队列的判空

bool QueueEmpty(Qe* q)
{return q->head->next == NULL;
}

 队列的判空就是判断第一个节点是否为空,return 一个 表达式即可,也可以用if else 语句。因人而异。

创造一个节点

Qnode* CreateNode(QeDataType x)
{Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));newnode->data = x;newnode->next = NULL;return newnode;
}

 创造一个节点在链表的初始化和插入都会用到,在之前链表的那篇博客有讲到,偏简单。

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

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

相关文章

asp.net校园二手交易平台系统VS开发sqlserver数据库web结构c#编程计算机网页

一、源码特点 asp.net校园二手交易平台系统 是一套完善的web设计管理系统&#xff0c;系统采用mvc模式&#xff08;BLLDALENTITY&#xff09;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 vs2010&#xff0c;数据库为sqlserver2008&a…

pytorch单精度、半精度、混合精度、单卡、多卡(DP / DDP)、FSDP、DeepSpeed模型训练

pytorch单精度、半精度、混合精度、单卡、多卡&#xff08;DP / DDP&#xff09;、FSDP、DeepSpeed&#xff08;环境没搞起来&#xff09;模型训练代码&#xff0c;并对比不同方法的训练速度以及GPU内存的使用 代码&#xff1a;pytorch_model_train FairScale&#xff08;你真…

[工业自动化-22]:西门子S7-15xxx编程 - 软件编程 - 如何PLC建立用户界面: SIMATIC 面板式HMI 或工控机PC HMI

目录 前言&#xff1a; 一、PLC&#xff08;可编程逻辑控制器&#xff09;的用户界面支持方式 1.1 概述 1.2 西门子&#xff08;Siemens&#xff09;的人机界面&#xff08;HMI&#xff09;支持多种类型 1.3 PC HMI VS SIMATIC HMI 二、PC—HMI—PLC连接架构的实现 三、…

Go——一、Go语言安装及介绍

Go 一、Windows下安装Go1、下载Go2、配置环境变量3、下载Jetbrain下的GoLang4、编写hello world5、编译和执行 二、Go语言介绍1、开发文档2、Go语言核心开发团队3、为什么要创建Go4、Go语言发展史5、Go语言特点6、Golang执行过程6.1 执行过程分析6.2 编译是什么 7、开发注意事项…

WinForms C# 导入和导出 CSV 文件 Spread.NET

使用 WinForms C# 和 VB.NET 导入和导出 CSV 文件 2023 年 11 月 17 日 使用 Spread.NET 直接在 .NET WinForms 应用程序中处理 CSV 文件。 Spread.NET可帮助您创建电子表格、网格、仪表板和表单。它包括一个强大的计算引擎&#xff0c;具有 450 多个函数以及导入和导出 Micros…

【OpenCV】仿射变换中cv2.estimateAffine2D 的原理

目录 一、介绍 二、仿射变换矩阵 (M) 1.M中六个元素的说明 2.计算旋转角度 3.M的计算过程 三、输出状态 (inliers) 四、错切参数 一、介绍 cv2.estimateAffine2D 是 OpenCV 库中的一个函数&#xff0c;用于估计两个二维点集之间的仿射变换矩阵。即第一个点集经仿射变换转…

解决Requests中使用httpbin服务器问题:自定义URL的实现与验证

问题背景 在使用Python的Requests模块进行单元测试时&#xff0c;可能会遇到无法使用本地运行的httpbin服务器进行测试的问题。这是因为测试脚本允许通过环境变量HTTPBIN_URL指定用于测试的本地httpbin实例&#xff0c;但在某些测试用例中&#xff0c;URL是硬编码为httpbin.or…

成都瀚网科技有限公司抖音带货可靠么

近年来&#xff0c;随着抖音等短视频平台的兴起&#xff0c;越来越多的企业开始利用这些平台进行产品推广和销售。成都瀚网科技有限公司也紧跟这一趋势&#xff0c;通过抖音开展带货业务。那么&#xff0c;成都瀚网科技有限公司的抖音带货是否可靠呢&#xff1f;本文将对此进行…

KylinOSv10修改ulimit值

问题 ulimit 值过小&#xff0c;可能导致压力测试遇到瓶颈&#xff0c;比如通过nginx建立tcp长链接时&#xff0c;链接数量受限。需要修改ulimit值&#xff0c;Linux默认为1024。 解决 使用root或sudo权限&#xff0c;编辑文件/etc/security/limits.conf&#xff0c;新增以下…

pipeline + node +jenkins+kubernetes部署yarn前端项目

1、编写Dockerfile文件 # Set the base image FROM node:16.10.0# WORKDIR /usr/src/app/ WORKDIR /home/option# Copy files COPY ./ /home/option/# Build arguments LABEL branch${BRANCH} LABEL commit${COMMIT} LABEL date${BUILD_DATE} ARG ENV# Set ENV variables ENV …

基于C++实现循环赛日程表(分治算法)

一、问题描叙 设有n2^k个运动员&#xff0c;要进行网球循环赛。现在要设计一个满足以下要求的比赛日程表 每个选手必须与其他n-1个选手各赛一场每个选手一天只能赛一次循环赛一共进行n-1天 二、问题分析 按此要求可将比赛日程表设计成n行n-1列的表&#xff0c;在表中第 i 行…

金属压块液压打包机比例阀放大器

液压打包机是机电一体化产品&#xff0c;主要由机械系统、液压控制系统、上料系统与动力系统等组成。整个打包过程由压包、回程、提箱、转箱、出包上行、出包下行、接包等辅助时间组成。市场上液压打包机主要分为卧式与立式两种&#xff0c;立式废纸打包机的体积比较小&#xf…

Hive数据表操作--学习笔记

1&#xff0c;Hive数据表操作 1&#xff0c;建表语句和内外部表 ①创建内部表 create [external] table [if not exists] 表名( 字段名 字段类型 [comment 注释], 字段名 字段类型 [comment 注释], ... ) [row format delimited fields terminated by 指定分隔符];&#xff0…

如何简单挖掘公益SRC?

目录 1、寻找漏洞 1)谷歌语法 2)fofa 2、挖掘漏洞 3、提交报告 第一步&#xff1a;“标题”和“厂商信息”和“所属域名” 第二步&#xff1a;其它内容 第三步&#xff1a;复现步骤 0、IP域名归属证明 1、漏洞页 2、该干啥 3、注入的结果 4、上榜吉时 时间&#x…

【开源】基于JAVA的快递管理系统

项目编号&#xff1a; S 007 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S007&#xff0c;文末获取源码。} 项目编号&#xff1a;S007&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 快递类型模块2.3 快…

Springboot 对于数据库字段加密方案(此方案是对字符串处理的方案)

背景:在erp开发中&#xff0c;有些用户比较敏感数据库里的数据比较敏感&#xff0c;系统给用户部署后&#xff0c;公司也不想让任何人看到数据&#xff0c;所以就有了数据库字段加密方案。 技术 spring boot mybatisplus 3.3.1 mybatisplus 实际提供了 字段加密方案 第一 他…

Java智慧工地SaaS管理平台源码:AI/云计算/物联网

智慧工地是指运用信息化手段&#xff0c;围绕施工过程管理&#xff0c;建立互联协同、智能生产、科学管理的施工项目信息化生态圈&#xff0c;并将此数据在虚拟现实环境下与物联网采集到的工程信息进行数据挖掘分析&#xff0c;提供过程趋势预测及专家预案&#xff0c;实现工程…

Elastic Search的RestFul API入门:index索引的增删改查

在我们开始深入探讨Elasticsearch的Restful API之前&#xff0c;有一点非常重要&#xff0c;那就是Elasticsearch存储的数据是JSON结构的。JSON&#xff0c;全称JavaScript Object Notation&#xff0c;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时…

拜耳阵列(Bayer Pattern)以及常见彩色滤波矩阵(CFA)

一、拜耳阵列的来源 图像传感器将光线转化成电流&#xff0c;光线越亮&#xff0c;电流的数值就越大&#xff1b;光线越暗&#xff0c;电流的数值就越小。图像传感器只能感受光的强弱&#xff0c;无法感受光的波长。由于光的颜色由波长决定&#xff0c;所以图像传播器无法记录…

解决 VS2022 关于 c++17 报错: C2131 表达式必须含有常量值

使用 VS2022 编译 ORB-SLAM3 加载Vocabulary 二进制ORBvoc.bin 时&#xff0c;在 DBOW2 里修改 TemplatedVocabulary.h 代码显示这样的错误&#xff1a; 编译器错误 C2131 表达式的计算结果不是常数 定位到我的代码中&#xff1a; char buf [size_node] ; 原因 &#xff1a; …