数据结构------栈(Stack)和队列(Queue)

也是好久没写博客了,那今天就回归一下,写一篇数据结构的博客吧。今天要写的是栈和队列,也是数据结构中比较基础的知识。那么下面开始今天要写的博客了。

目录

栈(Stack)

队列(Queue)

喜欢就点个赞吧。


栈(Stack)

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除 操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out) 的原则。

 

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

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

简单描述栈的特点:栈数据的增删都是在一头进行,即在栈顶


那栈又该如何创建与使用呢?他的原理又是怎样的,这里我们就用C语言实现一下。

我们这里就要想这个栈是要用数组来实现还是用链表来实现呢?其实我们可以从其功能开始思考,这两者哪个更好去实现栈的功能,而且效率较高,其实说到这里,很多人可能已经有了结果,其实要说简洁与效率数组更适合来做栈。那么我们下面就来完成一下这个代码完成一个栈。

这里先给头文件因为其中有typedef来命名的类型,以免各位佬看得迷惑。

头文件

这里解释一下DataType是各位做栈时储存数据的类型,需要改变时只需要在头文件里改动一下即可,例如你想变成char类型的数据,即可将typedef int DataType; 改为 typedef char DataType;
然后栈的结构体我们就用ST来简化方便写代码。

然后top为栈的数据个数,capacity就表示栈的容量
 

#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
typedef int DataType;typedef struct Stack
{DataType* a;int top;int capacity;}ST;void StackInit(ST* ps);
void StackDestory(ST* ps);
// 入栈
void StackPush(ST* ps, DataType x);
// 出栈
void StackPop(ST* ps);
DataType StackTop(ST* ps);int StackSize(ST* ps);
bool StackEmpty(ST* ps);

 

栈的格式化

void StackInit(ST* ps)
{assret(ps);ps->a = (DataType)mallco(4 * (sizeof(DataType)));if (ps->a == NULL){printf("malloc fail\n");exit(-1);}ps->capacity = 4;ps->top = 0;}

先将数组a  mallco出四个数据的大小,然后将容量capacity改为4.


栈的销毁

void StackDestory(ST* ps){assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;}

使用完栈后进行销毁得函数,防止内存泄露。 及时free掉,然后将a指向NULL。


入栈 

void StackPush(ST* ps, DataType x)
{assert(ps);if (ps->top == ps->capacity){DataType* tem = (DataType*)recalloc(ps->a, 2*ps->capacity*sizeof(DataType));if (tem == NULL){printf("racallco fail\n");}else{ps->a = tem;ps->capacity = 2 * ps->capacity;}}ps->a[ps->top] = x;ps->top++;}

第一个if,先判断数组a是否还有空间入栈,如果满了就进行recallco增容即可增容我们现在时增容两倍较为合适,recallco的用法在前面动态内存创建的文章已经讲过了。所以现在就不多解释了。入栈后记得将top++一下 。


出栈

void StackPop(ST* ps)
{assert(ps);assert(ps->top > 0);ps->top--;
}

这里就比较简单粗暴将top--,即可将原本栈顶得书局给屏蔽即可。


求栈的长度和判断栈是否为空 

int StackSize(ST* ps)
{assert(ps);return ps->top;
}bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

 

接下来我们就来看看队列


队列(Queue)

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先 进先出FIFO(First In First Out)

 

队列的特点:队列与栈的不同是他是在一头进行增数据,一头删数据,而栈数据的增删都是在一头。

 然后我们思考一下队列的功能实现是要数组好还是链表好呢,这么一想是不是马上就发现了,如果们还是用数组来实现的话,那么其出队列的时间复杂度为O(N),那么效率太低了,而链表实现的话则是O(1),显而易队列还是用链表实现较好。


下面就是队列函数的实现了。

还是先给大家看看头文件

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>typedef int Type;typedef struct Queuenode 
{Type* date;struct Queue* next;}Node;typedef struct Queue
{Node* head;Node* tail;
}Queue;void QueueInit(Queue* pq);
void QueueDestory(Queue* pq);// 队尾入
void QueuePush(Queue* pq, Type x);
// 队头出
void QueuePop(Queue* pq);

这里解释一下为什么创建了两个结构体 ,因为其中一个作为链表的节点而另一个队列结构体。队列的结构体我们只需要要一个队头和队尾。


 队列的格式化

 

void QueueInit(Queue* pq)
{assert(pq);pq->head = NULL;pq->tail = NULL;}

很简单将队头和队尾指向空NULL即可。


队列的销毁

void QueueDestory(Queue* pq)
{assert(pq);Node* cur = pq->head;while (cur){Node* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;}

 这里我们运用一个while循环,创建一个辅助指针来保存节点的下一个。不断free 掉即可。

注意要将队头和队尾指空NULL。


进队

 

void QueuePush(Queue* pq, Type x)
{assert(pq);Node* new = (Node*)mallco(sizeof(Node));if (new == NULL){printf("mallco fail\n");}new->date = x;new->next = NULL;if (pq->tail = NULL){pq->tail = new;pq->head = new;}else{pq->tail->next = new;pq->tail = new;}}

 我们mallco一个空间,作为进队的一个节点,然后对节点进行赋值,然后对链表进行尾插就完成了一半了。

需要注意的是记得把原来的tail的next 指向新节点,也要把tail改为 新节点,因为尾插后new就为最后的节点也就是尾了。注意当前有没有节点那将head和tail至为new即可。


出队

void QueuePop(Queue* pq)
{assert(pq);assert(pq->head);if (pq->head->next == NULL){free(pq->head);pq->head = NULL;pq->tail = NULL;}Node* next = pq->head->next;free(pq->head);pq->head = next;}

 这里也是根据队列的删数据特点,这里的出队就是头删了,我们先把head的next保存住,然后free掉head,再然后让next作为新的头。

 


 今天就结束了,希望您能喜欢这篇文章。

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

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

相关文章

AI论文速读 | 立场观点:时间序列分析,大模型能告诉我们什么?

题目&#xff1a;Position Paper: What Can Large Language Models Tell Us about Time Series Analysis 作者&#xff1a;Ming Jin ; Yifan Zhang ; Wei Chen ; Kexin Zhang ; Yuxuan Liang ; Bin Yang ; Jindong Wang ; Shirui Pan ; Qingsong Wen 机构&#xff1a;莫纳什大…

form 表单 转换为json-多种(通用/多维数组) 全方案

JSON 在 JavaScript 中重要&#xff0c;因其轻量、通用、易读&#xff0c;适用于数据交换、存储和传输。 为什么写这个文章&#xff0c;废话不多&#xff0c;直接近主题。 一、通用 一般采用jquery编写 var key $(#"cyberwin_form_card_newadd").serialize(); 结…

类和对象(2)——距离C++又近了一步

目录 一、构造函数 1.1声明和定义构造函数 1.2成员名和参数名 1.3构造函数的使用 1.4初始化列表 二、析构函数 2.1析构函数的概念 2.2析构函数的性质 三、拷贝构造函数 四、赋值运算符重载 4.1运算符重载 4.2赋值运算符重载 一、构造函数 我们知道&#xff0c;C中…

ZMQ的介绍与应用

文章目录 一、ZMQ是什么二、ZMQ的特点三、ZMQ的优缺点优点&#xff1a;缺点 四、ZMQ的应用场景 一、ZMQ是什么 zmq是ZeroMQ的简称&#xff0c;它是一个传输层的socket库&#xff0c;旨在使Socket编程更加简单、简洁和高效。它是一个消息处理队列库&#xff0c;可以在多个线程、…

项目解决方案: 实时视频拼接方案介绍

目 录 1、实时视频拼接概述 2、适用场景 3、系统介绍 3.1拼接形式 3.1.1横向拼接 3.1.2纵向拼接 3.2前端选择 3.2.1前端类型 3.2.2推荐配置 3.3后端选择 3.3.1录像回放 3.3.2客户端展示 4、拼接方案介绍 4.1基于4K摄像机的拼接方案 4.1.1系统架构…

Pytorch从零开始实战19

Pytorch从零开始实战——生成手势图像 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——生成手势图像环境准备模型选择模型训练模型分析总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c;Pytorch2.0.1cu118&…

算法|344.反转字符串 541. 反转字符串II 卡码网:54.替换数字 151.翻转字符串里的单词 卡码网:55.右旋转字符串

344.反转字符串 考察reverse&#xff0c; 也可以用其他方法 /** * param {character[]} s* return {void} Do not return anything, modify s in-place instead.*/ var reverseString function (s) {return s.reverse(); };541. 反转字符串 思路&#xff1a; 一般是i&#…

vue-router4 (七) 滚动行为(scrollBehavior )

应用场景&#xff1a; 从A组件进入B组件&#xff0c;再返回A组件后&#xff0c;想让A组件的页面回到进入B组件前的位置&#xff0c;或者自动刷新回到A组件顶部&#xff0c;就需配置路由的滚动行为&#xff08;scrollBehavior &#xff09;。 ①返回A组件时&#xff0c;让A组件…

webrtc

stun服务 阿里云服务器安全组添加端口开放 webrtc-streamer视屏流服务器搭建 - 简书

Prometheus-监控远程linux的主机

一、本地访问 1、访问 http://8.137.122.212:9090/2、查看监控的主机 默认只监控了本机一台主机 这里的IP地址原本是‘localhost’&#xff0c;为了方便我将‘localhost’换成了主机的IP地址 现在看只监控了本机一台主机 3、查看监控数据 通过http://8.137.122.212:9090/m…

RT-Thread studio上创建一个STM32F103的CAN通讯功能

前言 &#xff08;1&#xff09;如果有嵌入式企业需要招聘湖南区域日常实习生&#xff0c;任何区域的暑假Linux驱动实习岗位&#xff0c;可C站直接私聊&#xff0c;或者邮件&#xff1a;zhangyixu02gmail.com&#xff0c;此消息至2025年1月1日前均有效 &#xff08;2&#xff0…

学Python如此简单--用Python实现一个超简单的学生信息管理系统

简介 系统名称&#xff1a;番茄系统 实现功能&#xff1a;增删查改 运用技术&#xff1a;python基础 代码 import time student_all [] print(欢迎进入番茄系统.center(30)) print(**36,end) while True:pee 请选择功能&#xff1a;1、添加学生2、删除学生3、修改学生4、…

1.1 编程环境的安装

汇编语言 汇编语言环境部署 第二个运行程序直接双击安装一直下一步即可MASM文件复制到D盘路径下找到dosbox安装路径&#xff1a;C:\Program Files (x86)\DOSBox-0.74找到该文件双击打开它&#xff0c;修改一下窗口大小 把这两行改成如下所示 运行dos&#xff0c;黑框中输入mou…

C#,数值计算,求解微分方程的吉尔(Gear)四阶方法与源代码

1 微分方程 微分方程&#xff0c;是指含有未知函数及其导数的关系式。解微分方程就是找出未知函数。 微分方程是伴随着微积分学一起发展起来的。微积分学的奠基人Newton和Leibniz的著作中都处理过与微分方程有关的问题。微分方程的应用十分广泛&#xff0c;可以解决许多与导数…

RTCA DO-178C 机载系统和设备认证中的软件注意事项-软件配置管理流程(七)

7.0 软件配置管理流程 SOFTWARE CONFIGURATION MANAGEMENT PROCESS 本节讨论软件配置管理 (SCM) 过程的目标和活动。 SCM 流程按照软件计划流程&#xff08;参见 4&#xff09;和软件配置管理计划&#xff08;参见 11.4&#xff09;的定义进行应用。 SCM 过程的输出记录在软件…

【探索AI】Sora - 探索AI视频模型的无限可能

Sora - 探索AI视频模型的无限可能 随着人工智能技术的飞速发展&#xff0c;AI视频模型已成为科技领域的新热点。而在这个浪潮中&#xff0c;OpenAI推出的首个AI视频模型Sora&#xff0c;以其卓越的性能和前瞻性的技术&#xff0c;引领着AI视频领域的创新发展。让我们将一起探讨…

【Web安全靶场】sqli-labs-master 21-37 Advanced-Injection

sqli-labs-master 21-37 Advanced-Injection 第一关到第二十关请见专栏 文章目录 sqli-labs-master 21-37 Advanced-Injection第二十一关-Cookie注入第二十二关-Cookie注入第二十三关-注释符过滤的报错注入第二十四关-二次注入第二十五关-过滤OR、AND双写绕过第二十五a关-过滤…

老卫带你学---leetcode刷题(190. 颠倒二进制位)

190. 颠倒二进制位 问题 颠倒给定的 32 位无符号整数的二进制位。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff08;如 Java&#xff09;中&#xff0c;没有无符号整数类型。在这种情况下&#xff0c;输入和输出都将被指定为有符号整数类型&#xff0c;并且不应…

《Flask入门教程》学习笔记

《Flask入门教程》官网&#xff1a;https://tutorial.helloflask.com/ 目录 第一章&#xff1a;准备工作第二章&#xff1a;Hello, Flask!第三章&#xff1a;模板第四章&#xff1a;静态文件第五章&#xff1a;数据库第六章&#xff1a;模板优化第七章&#xff1a;表单第八章&a…

【嵌入式——QT】日期与定时器

日期 QTime&#xff1a;时间数据类型&#xff0c;仅表示时间&#xff0c;如 16:16:16&#xff1b;QDate&#xff1a;日期数据类型&#xff0c;仅表示日期&#xff0c;如2024-1-22&#xff1b;QDateTime&#xff1a;日期时间数据类型&#xff0c;表示日期和时间&#xff0c;如2…