初阶数据结构之栈和队列

栈和队列是两种特殊的线性表,都可以用数组或者链表来实现,接下来就让我们看看栈和队列会有什么奥秘吧~ 

目录

1.栈

1.1栈的概念

1.2栈的实现

1.2.1 Stack.h

1.2.2 Stack.c

1.2.3 test.c

2.队列

2.1队列的概念

2.2队列的实现

2.2.1 Queue.h

2.2.2 Queue.c 

2.2.3 test.c


1.栈

1.1栈的概念

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

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

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

1.2栈的实现

由于栈的特点是后进先出,对最后一个元素操作频繁,且无对中间元素的增删查改,故常选择数组(顺序表)来实现栈 

ps:感觉栈就是残疾的顺序表(不敢吱声)

1.2.1 Stack.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int STDateType;
typedef struct Stack {STDateType* _a;//栈底int _top;//栈顶int _capacity;//容量
}Stack;//初始化
void STInit(Stack* ps);
//销毁
void STDestroy(Stack* ps);
//压栈
void STPush(Stack* ps, STDateType date);
//出栈
void STPop(Stack* ps);
//获取栈顶元素
STDateType STTop(Stack* ps);
//获取栈中有效数据个数
int STSize(Stack* ps);
//判断栈是否为空
bool STEmpty(Stack* ps);
//打印栈中元素
void STPrint(Stack* ps);

1.2.2 Stack.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"//初始化
void STInit(Stack* ps)
{assert(ps);ps->_a = NULL;ps->_capacity = 0;ps->_top = 0;
}
//销毁
void STDestroy(Stack* ps)
{assert(ps);free(ps->_a);ps->_a = NULL;ps->_capacity = 0;ps->_top = 0;
}
//压栈
void STPush(Stack* ps, STDateType date)
{assert(ps);if (ps->_capacity == ps->_top){int newcapacity = (ps->_top == 0 ? 4 : 2 * ps->_capacity);STDateType* p = (STDateType*)realloc(ps->_a, newcapacity * sizeof(STDateType));if (p == NULL){perror("realloc p false");return;}else {ps->_a = p;}ps->_capacity = newcapacity;}ps->_a[ps->_top] = date;ps->_top++;
}
//出栈
void STPop(Stack* ps)
{assert(ps);assert(ps->_top);ps->_top--;
}
//获取栈顶元素
STDateType STTop(Stack* ps)
{assert(ps);return ps->_a[ps->_top - 1];
}
//获取栈中有效数据个数
int STSize(Stack* ps)
{assert(ps);return ps->_top;
}
//判断栈是否为空
bool STEmpty(Stack* ps)
{assert(ps);if (ps->_top == 0){return true;}else {return false;}
}
//打印栈中元素
void STPrint(Stack* ps)
{assert(ps);int i = 0;for(i = 0; i < ps->_top; i++){printf("%d->", ps->_a[i]);}printf("NULL\n");
}

1.2.3 test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
int main()
{Stack st;STInit(&st);STPush(&st, 1);STPush(&st, 2);STPush(&st, 3);STPush(&st, 4);STPush(&st, 5);STPrint(&st);STPop(&st);STPrint(&st);STPush(&st, 6);STPrint(&st);int a = STTop(&st);printf("a=%d\n", a);int size = STSize(&st);printf("size=%d\n", size);STPop(&st);STPop(&st);STPop(&st);STPop(&st);STPop(&st);int size2 = STSize(&st);printf("size2=%d\n", size2);bool empty = STEmpty(&st);printf("empty=%d\n", empty);STDestroy(&st);return 0;
}

2.队列

2.1队列的概念

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

入队列:进行插入操作的一端称为队尾

出队列:进行删除操作的一端称为队头

2.2队列的实现

根据队列一端进,一端出的特点,可知对头、尾元素操作频繁,若用数组,在删除队头元素时要进行大量元素的挪动,故我们常选择链表实现。 

2.2.1 Queue.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int QDataType;
typedef struct QueueNode //控制队列中的一个节点
{QDataType val;struct QueueNode* next;
}QNode;typedef struct Queue //控制整条队列
{QNode* head;QNode* tail;int size;
}Queue;// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);
// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);
//打印
void QueuePrint(Queue* q);

2.2.2 Queue.c 

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"// 初始化队列 
void QueueInit(Queue* q)
{assert(q);q->head = q->tail = NULL;q->size = 0;}
// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{assert(q);QNode* cur = (QNode*)malloc(sizeof(QNode));if (cur == NULL){perror("malloc q fail");return;}cur->val = data;cur->next = NULL;if (QueueEmpty(q)){q->head = q->tail = cur;}else {q->tail->next = cur;q->tail = cur;}q->size++;
}
// 队头出队列 
void QueuePop(Queue* q)
{assert(q);assert(q->head);QNode* cur = q->head;if (cur->next == NULL){q->head = q->tail = NULL;}else{q->head = cur->next;}free(cur);cur = NULL;q->size--;
}
// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{assert(q);assert(q->head);return q->head->val;
}
// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{assert(q);assert(q->tail);return q->tail->val;
}
// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{assert(q);return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q)
{assert(q);return q->head == NULL;
}
// 销毁队列 
void QueueDestroy(Queue* q)
{assert(q);QNode* cur = q->head;while (cur){QNode* del = cur;cur = cur->next;free(del);}
}
//打印
void QueuePrint(Queue* q)
{assert(q);QNode* cur=q->head;while (cur){printf("%d->", cur->val);cur = cur->next;}printf("NULL\n");
}

2.2.3 test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"
int main()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePush(&q, 5);int size=QueueSize(&q);printf("size=%d\n", size);int head=QueueFront(&q);printf("head=%d\n", head);int tail = QueueBack(&q);printf("tail=%d\n", tail);QueuePrint(&q);QueuePop(&q);QueuePop(&q);QueuePop(&q);size = QueueSize(&q);printf("size=%d\n", size);head = QueueFront(&q);printf("head=%d\n", head);tail = QueueBack(&q);printf("tail=%d\n", tail);bool t = QueueEmpty(&q);printf("%d\n", t);QueuePrint(&q);QueueDestroy(&q);return 0;
}

栈和队列属于线性表中比较简单的两环(当然是在掌握了链表之后),相信你勤加练习,多多思考,肯定能够将它们掌握 !

---------------------------------------------------------------------------------------------------------------------------------

好啦,那这次的分享就到这里,希望看到这里的小伙伴可以多多支持一下鱼头,点赞关注加收藏哦~

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

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

相关文章

探索WebKit的WebUSB API:开启浏览器与硬件的无缝对话

探索WebKit的WebUSB API&#xff1a;开启浏览器与硬件的无缝对话 在当今技术日益融合的时代&#xff0c;浏览器已成为连接用户与各种硬件设备的重要桥梁。WebKit的WebUSB API为Web开发者提供了一种新的方式&#xff0c;允许网页直接与USB设备进行通信&#xff0c;无需安装任何…

【科研】# Taylor Francis 论文 LaTeX template模版 及 Word模版

【科研写论文】系列 文章目录 【科研写论文】系列前言一、Word 模板&#xff08;附下载网址&#xff09;&#xff1a;二、LaTeX 版本方法1&#xff1a;直接网页端打开&#xff08;附网址&#xff09;方法2&#xff1a;直接下载到本地电脑上编辑下载地址说明及注意事项 前言 给…

【Gin】精准应用:Gin框架中工厂模式的现代软件开发策略与实施技巧(下)

【Gin】精准应用&#xff1a;Gin框架中工厂模式的现代软件开发策略与实施技巧(下) 大家好 我是寸铁&#x1f44a; 【Gin】精准应用&#xff1a;Gin框架中工厂模式的现代软件开发策略与实施技巧(下)✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言 本次文章分为上下两部分&…

配置web服务器练习

4练习要求&#xff1a; 练习一&#xff1a;配置web服务器&#xff0c;当访问网站 www.haha.com 时显示&#xff1a;haha 练习二&#xff1a;配置web服务器&#xff0c;当访问网站 www.xixi.com/secret/ 时显示&#xff1a;this is secret 具体步骤&#xff1a; 1、配置yum…

压测实操--produce压测方案

作者&#xff1a;九月 环境信息&#xff1a; 操作系统centos7.9&#xff0c;kafka版本为hdp集群中的2.0版本。 Producer相关参数 使用Kafka自带的kafka-producer-perf-test.sh脚本进行压测&#xff0c;该脚本参数为&#xff1a; 在producer涉及到性能的关键因素可能会存在如…

记录|使用HslCommunication库进行写入Real数据的坑

项目场景&#xff1a; 现在已经通过HslCommunication连接上了PLC&#xff0c;需要对DB1.DBD10的位置处进行数据写入。 问题描述 但是进行将12.2写入指定位置DB1.DBD10时&#xff0c;发现无法从博图中实时检测到数据的写入。 下面是我当时错误的数据写入方法&#xff1a;【主…

光伏发电管理软件:光伏企业的核心驱动力

光伏产业面对日益增长的装机容量、复杂多变的运维需求以及激烈的市场竞争&#xff0c;光伏企业如何高效管理、优化运营、提升效益&#xff0c;成为了行业关注的焦点。在此背景下&#xff0c;鹧鸪云光伏发电管理软件应运而生&#xff0c;并逐渐成为光伏企业的核心驱动力。 一、提…

回文数-双指针

题目描述&#xff1a; 个人题解&#xff1a; 先将整数转换成字符串&#xff0c;再利用双指针逐一比较数字。 代码实现&#xff1a; class Solution { public:bool isPalindrome(int x) {if(x<0||(x%100&&x!0)){return false;}//c标准库调用&#xff0c;将整数下转…

opencv - py_calib3d - py_calibration 相机校准

文章目录 Camera Calibration 相机校准目标基础知识代码设置校准去失真1. 使用 **cv.undistort()**2. 使用 **remapping** 重新投影误差 Camera Calibration 相机校准 目标 在本节中&#xff0c;我们将学习 相机造成的失真类型如何找到相机的内在和外在属性如何根据这些属性…

跨境电商平台:引领国际贸易新潮流

随着全球化的不断推进&#xff0c;跨境电商逐渐成为国际贸易的重要组成部分。它不仅为消费者带来了更多样化的商品选择&#xff0c;也为商家提供了更广阔的市场空间。本文将详细介绍跨境电商平台的相关知识&#xff0c;帮助读者更好地理解这一新兴领域的运作机制和市场前景。 …

防护勒索攻击:一场勒索攻击与智能防护的较量

近年来&#xff0c;云上数据安全已经成为企业的又一大难题&#xff0c;尤其是勒索攻击频发&#xff0c;有组织的黑客攻击目标已经从核心数据窃取扩展到金融、交通、能源、通信等行业的关键信息基础设施&#xff0c;对企业数据安全构成了极大的威胁和挑战。 同时AI时代&#xff…

Transformer模型基本原理、应用场景、优点与挑战,以及未来的发展趋势。

随着人工智能技术的飞速发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域也取得了显著的进步。其中&#xff0c;Transformer模型作为近年来NLP领域的重大突破&#xff0c;已经在众多任务中取得了卓越的性能。本文将对Transformer模型进行深入的探讨&#xff0c;包…

tcache attack

Tcache Attack tcache让堆利用更加简单&#xff1a; tcache回顾&#xff1a; 在 tcache 中新增了两个结构体&#xff0c;分别是 tcache_entry 和 tcache_perthread_struct&#xff1a; /* We overlay this structure on the user-data portion of a chunk when the chunk is …

功能教学——如何快速理解并使用数据助手

在企业的数字化管理中&#xff0c;数据处理的重要性不容小觑。它如同一根红线&#xff0c;贯穿企业运营的各个环节&#xff0c;对于提升决策效率、优化运营流程以及增强市场竞争力等方面都发挥着至关重要的作用。而百数的数据助手&#xff0c;作为一款高效的数据处理工具&#…

【MySQL】:表操作语法大全

表内容的操作 增删改查 CRUD (create、retrieve、update、delete) 新增 基本语法 语法为&#xff1a; insert into 表名 values (值&#xff0c;值&#xff0c;值...);这里的列数和类型&#xff0c;要和表结构匹配插入中文的话&#xff0c;要确保数据库创建的时候要设置字…

Failed to build get_cli:get:的解决方案

项目场景&#xff1a; 今天安装Getx命令行的时候&#xff0c;输入这面文档报了一个错&#xff1a; dart pub global activate get_cli 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 例如&#xff1a;数据传输过程中数据不时出现丢失的情况&#xff0c;偶尔…

数据传输校验

简单的异或校验 异或校验是一种简单且常用的校验方法。它将所有数据字节逐字节进行异或操作&#xff0c;最后得到的结果就是掩码。 def calculate_xor_checksum(data):checksum 0for byte in data:checksum ^ bytereturn checksumCRC&#xff08;循环冗余校验&#xff09; CR…

代码随想录算法训练营Day 63| 图论 part03 | 417.太平洋大西洋水流问题、827.最大人工岛、127. 单词接龙

代码随想录算法训练营Day 63| 图论 part03 | 417.太平洋大西洋水流问题、827.最大人工岛、127. 单词接龙 文章目录 代码随想录算法训练营Day 63| 图论 part03 | 417.太平洋大西洋水流问题、827.最大人工岛、127. 单词接龙17.太平洋大西洋水流问题一、DFS二、BFS三、本题总结 82…

基于SpringBoot的矩形范围面时空分析-以震中附近历史地震为例

目录 前言 1、分析的必要性 2、分析的紧迫性 一、数据库物理模型及空间分析实现 1、数据库物理模型 2、空间数据库中的空间查询分析 二、Java后台程序开发 1、模型层设计 2、业务层的设计与实现 三、WebGIS功能设计与实现 1、同时展示4幅地图 2、初始化地图 3、展示…

CID引流-拼多多案例

目前已实现拼多多等CID链路&#xff0c;本文以拼多多链路为例&#xff0c;说明具体实施过程 1. 拼多多链路流程 以下是通过前期调研&#xff0c;得到的具体业务流程&#xff1a; 商家申请资质以及授权部分&#xff0c;进行商品推广自研落地页&#xff0c;生成落地页在巨量引…