纯c语言模拟栈和队列(初学必看)

一、栈(Stack)

1.栈的概念及其结构

栈是一种特殊的线性表,在栈这个结构里,越先存进去的数据越难取出来。

这个结构就像是一个只有一端有打开的容器,越先放进去的球越在底部,想要把底部的球拿出来,就必须先把前面的求拿出来。像这种”先进后出“的结构就是栈

对于栈来说,我们只能在表尾进行插入或者删除,表

2.栈的功能

栈的基本操作主要有:栈的初始化、判空、判满、取栈顶元素、在栈顶进行插入和删除。在栈顶插入元素称为入栈,在栈顶删除元素称为出栈。

我们常用栈这种数据结构实现深度搜索。

由于栈的特性,我们只对栈顶进行取出元素或者是压入元素,所以我们在实现栈的时候需要用一个top指针来指向栈顶元素的地址或者是栈顶元素后面的地址。

3.c语言代码模拟(动态实现)

Stack.h文件:

这个文件用来声明功能函数以及栈结构体数据的定义。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int STDataType;
typedef struct Stack
{STDataType* _a;int _top;		// 栈顶int _capacity;  // 容量 
}Stack;
// 初始化栈 
void StackInit(Stack* ps);
// 入栈 
void StackPush(Stack* ps, STDataType data);
//打印
void StackPrint(Stack* ps);
// 出栈 
void StackPop(Stack* ps);
// 获取栈顶元素 
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数 
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps);
// 销毁栈 
void StackDestroy(Stack* ps);

Stack.c文件:

实现各种功能函数

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"// 初始化栈 
void StackInit(Stack* ps) {assert(ps);ps->_a = NULL;ps->_capacity = 0;ps->_top = 0;
}// 销毁栈 
void StackDestroy(Stack* ps) {assert(ps);free(ps->_a);ps->_a = NULL;ps->_capacity = 0;ps->_top = 0;
}
// 入栈 
void StackPush(Stack* ps, STDataType data) {assert(ps);if (ps->_top == ps->_capacity) {STDataType* temp = NULL;int newcap = 0;if (ps->_capacity == 0) {newcap = 4;}else {newcap = ps->_capacity * 2;}temp = (STDataType*)realloc(ps->_a,sizeof(STDataType) * newcap);if (temp == NULL) {perror("mallc:fail");}ps->_a = temp;ps->_capacity = newcap;}ps->_a[ps->_top] = data;ps->_top++;
}// 出栈 
void StackPop(Stack* ps) {assert(ps&&ps->_top>0);--ps->_top;//return ps->_a[--ps->_top];
}//打印
void StackPrint(Stack* ps) {assert(ps);printf("top=%d  cap=%d\n", ps->_top, ps->_capacity);for (int i = 0; i < ps->_top; i++) {printf("%d->", ps->_a[i]);}printf("\n");
}
// 获取栈顶元素 
STDataType StackTop(Stack* ps) {assert(ps&&ps->_top>0);return ps->_a[ps->_top - 1];
}
// 获取栈中有效元素个数 
int StackSize(Stack* ps) {assert(ps);return ps->_top;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps) {assert(ps);return ps->_top == 0;
}

test.c文件:

测试栈的功能是否达到预期 

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"void test1() {Stack st;StackInit(&st);StackPush(&st, 1);StackPush(&st, 2);StackPush(&st, 3);StackPush(&st, 4);StackPrint(&st);printf("弹出栈顶元素\n");StackPop(&st);StackPrint(&st);int x =StackTop(&st);printf("获取栈顶元素 %d\n",x);StackPrint(&st);printf("获取栈里有效元素个数 %d\n", StackSize(&st));printf("栈是否为空%d\n", StackEmpty(&st));StackDestroy(&st);
}
int main() {test1();return 0;
}

二、队列(Queue)

1、队列的概念及其结构

只在一端进行删除操作(出队),只在另一端进行添加操作(入队)--先进先出

 这个结构就像是在模拟,越先排队的人越先“打到饭”。(理论上不允许插队)

 看上去像不像排队打饭的你呢?

2.队列的功能

队列 的最主要用途是异步任务和通信两个方面 异步的思路主要用来缓解瞬间压力、耗时操作、并行任务等。

队列的基本功能是入队、出队、获得队列元素个数、判断队列是否为空等操作。

在算法中我们常用队列来实现广度优先遍历

3.c语言代码模拟

Queue.h文件:

声明功能函数以及栈结构体数据的定义

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int QDataType;// 链式结构:表示队列 
typedef struct QListNode
{struct QListNode* _next;QDataType _data;
}QNode;// 队列的结构 
typedef struct Queue
{QNode* _front;QNode* _rear;
}Queue;// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);
//打印队列信息
void QueuePrint(Queue* q);
// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);

Queue.c文件:

实现各种功能函数

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"// 初始化队列 
void QueueInit(Queue* q) {assert(q);q->_front = NULL;q->_rear = NULL;
}
//创造节点
QNode* CreatNode(QDataType x) {QNode* newnode =(QNode*) malloc(sizeof(QNode));if (newnode == NULL) {perror("malloc:fail");}newnode->_next = NULL;newnode->_data = x;return newnode;
}// 队尾入队列 
void QueuePush(Queue* q, QDataType data) {assert(q);QNode* newnode = CreatNode(data);if (q->_rear == NULL) {q->_front=q->_rear = newnode;}else {q->_rear->_next = newnode;q->_rear = newnode;}
}// 队头出队列 
void QueuePop(Queue* q) {assert(q&&q->_front!=NULL);QNode* head = q->_front;if (q->_front == q->_rear) {q->_front = q->_rear = NULL;}else {q->_front = q->_front->_next;}free(head);head = NULL;
}
//打印队列信息
void QueuePrint(Queue* q) {assert(q&&q->_rear!=NULL);QNode* cur = q->_front;printf("队头指向%d 队尾指向%d\n", q->_front->_data, q->_rear->_data);while (cur != NULL) {printf("%d->", cur->_data);cur = cur->_next;}printf("\n");
}
// 获取队列头部元素 
QDataType QueueFront(Queue* q) {assert(q&&q->_front!=NULL);return q->_front->_data;
}// 获取队列队尾元素 
QDataType QueueBack(Queue* q) {assert(q&&q->_rear!=NULL);return q->_rear->_data;
}// 获取队列中有效元素个数 
int QueueSize(Queue* q) {assert(q);int size_q = 0;QNode* cur = q->_front;while (cur) {size_q++;cur = cur->_next;}return size_q;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q) {assert(q);return q->_front == NULL;
}
// 销毁队列 
void QueueDestroy(Queue* q) {assert(q&&q->_front!=NULL);QNode* cur = q->_front;while (cur) {QNode* temp = cur->_next;free(cur);cur = temp;}q->_front = q->_rear = NULL;
}

test.c文件:

测试队列功能

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"void test1() {Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePush(&q, 5);QueuePrint(&q);printf("弹出队头元素\n");QueuePop(&q);QueuePrint(&q);printf("队列元素个数%d\n", QueueSize(&q));printf("队列队头元素%d 队尾元素%d\n", QueueFront(&q), QueueBack(&q));QueuePrint(&q);QueueDestroy(&q);printf("%p %p", q._front, q._rear);
}int main() {test1();return 0;
}

 

总结

栈和队列都是数据结构中比较基础同时也是必须深刻掌握的数据结构,自己去模拟一遍它们的各种功能有利于加深自己对其的理解,同时也能提高自己的代码思维。我认为对于初学者来说是打基础的一种很好的方式。 

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

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

相关文章

树莓派4B的测试记录(CPU、FFMPEG)

本文是用来记录树莓派 4B 的一些测试记录。 温度 下面记录中的风扇和大风扇是这样的&#xff1a; 为什么要用大风扇呢&#xff1f;因为小风扇在外壳上&#xff0c;气流通过外壳的珊格会有啸叫&#xff0c;声音不大但是很烦人&#xff0c;大风扇没这个问题&#xff0c;并且同样…

Vue3 数据响应式原理:Proxy和Reflect

我们在Vue2中使用的是Object.defineProperty方法来实现数据响应式的&#xff0c;可以通过get和set方法来监听对象的访问和修改。 但是并不能响应对象中属性的增加和删除&#xff0c;只能使用Vue.$set 和Vue.$delete 来对对象中的属性进行增加和删除。 数组也不能直接通过下标…

PyCharm因安装了illuminated Cloud插件导致加载项目失败

打开Pycharm时会有弹窗提示&#xff1a; The license for Illuminated Cloud is invalid or has expired. All Illuminated Cloud features will be disabled. 这个弹窗会导致你加载项目一直失败&#xff0c;close project 也关不掉&#xff0c;我都是用任务管理器杀死进程的…

Jmeter 性能 —— 负载阶梯场景!

1、安装阶梯测试的第三方插件->搜jpgc 选项-JMeter Plugins Manager -搜jpgc 空格&#xff0c;然后安装 2、脚本-线程组选jpgc Stepping Thread Group 最终并发数为100&#xff0c;并发数从0开始&#xff0c;5秒内增加10个并发数&#xff0c;增加10个后持续30s&#xff0c;…

taro(踩坑) npm run dev:weapp 微信小程序开发者工具预览报错

控制台报错信息&#xff1a; VM72:9 app.js错误: Error: module vendors-node_modules_taro_weapp_prebundle_chunk-JUEIR267_js.js is not defined, require args is ./vendors-node_modules_taro_weapp_prebundle_chunk-JUEIR267_js.js 环境&#xff1a; node 版本&#x…

Spring Boot(二)

1、运行维护 1.1、打包程序 SpringBoot程序是基于Maven创建的&#xff0c;在Maven中提供有打包的指令&#xff0c;叫做package。本操作可以在Idea环境下执行。 mvn package 打包后会产生一个与工程名类似的jar文件&#xff0c;其名称是由模块名版本号.jar组成的。 1.2、程序…

vue分片上传视频并转换为m3u8文件并播放

开发环境&#xff1a; 基于若依开源框架的前后端分离版本的实践&#xff0c;后端java的springboot&#xff0c;前端若依的vue2&#xff0c;做一个分片上传视频并分段播放的功能&#xff0c;因为是小项目&#xff0c;并没有专门准备文件服务器和CDN服务&#xff0c;后端也是套用…

2023NewStarCTF

目录 一、阳光开朗大男孩 二、大怨种 三、2-分析 四、键盘侠 五、滴滴滴 六、Include? 七、medium_sql 八、POP Gadget 九、OtenkiGirl 一、阳光开朗大男孩 1.题目给出了secret.txt和flag.txt两个文件&#xff0c;secret.txt内容如下&#xff1a; 法治自由公正爱国…

【Redis】list常用命令内部编码使用场景

文章目录 前置知识列表类型的特点 命令LPUSHLPUSHXRPUSHRPUSHXLRANGELPOPRPOPLINDEXLREMLINSERTLTRIMLSETLLEN 阻塞版本命令BLPOPBRPOP 命令总结内部编码测试内部编码 使用场景消息队列分频道的消息队列 模拟栈和队列 前置知识 列表类型是⽤来存储多个有序的字符串&#xff0c…

第一次实操Python+robotframework接口自动化测试

目前我们需要考虑的是如何实现关键字驱动实现接口自动化输出&#xff0c;通过关键字的封装实现一定意义上的脚本与用例的脱离&#xff01; robot framework 的安装不过多说明&#xff0c;网上资料比较太多~ 实例&#xff1a;&#xff01;&#xff01;&#xff01;&#xff01…

AI:80-基于深度学习的医学图像分割与病变识别

🚀 本文选自专栏:人工智能领域200例教程专栏 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的代码,详细讲解供大家学习,希望可以帮到大家。欢迎订阅支持,正在不断更新中,…

Flink SQL 表值聚合函数(Table Aggregate Function)详解

使用场景&#xff1a; 表值聚合函数即 UDTAF&#xff0c;这个函数⽬前只能在 Table API 中使⽤&#xff0c;不能在 SQL API 中使⽤。 函数功能&#xff1a; 在 SQL 表达式中&#xff0c;如果想对数据先分组再进⾏聚合取值&#xff1a; select max(xxx) from source_table gr…

2022年06月 Python(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 Python中 print(“八进制{: o}”.format(12)) 正确的输出结果是?( ) A: 八进制:O B: 八进制:O14 C: 八进制14O D: 八进制14 答案:D 字符串的format()格式。 第2题 下列的程…

pychon/PIL/opencv/json学习过程中遇到的问题

1. 使用PIL.Image读取图片 注意&#xff1a;pytorch中对图像预处理是transforms的输入必须是PIL格式的文件&#xff0c;使用cv2读取的图片就按照第二条的代码处理&#xff08;3通道合并、归一化处理&#xff09; from PIL import Image img Image.open("test1.jpg"…

2023 年最新企业微信官方会话机器人开发详细教程(更新中)

目标是开发一个简易机器人&#xff0c;能接收消息并作出回复。 获取企业 ID 企业信息页面链接地址&#xff1a;https://work.weixin.qq.com/wework_admin/frame#profile 自建企业微信机器人 配置机器人应用详情 功能配置 接收消息服务器配置 配置消息服务器配置 配置环境变量…

如何利用 cpolar 内网穿透技术实现 U8 用友 ERP 异地访问

文章目录 前言1. 服务器本机安装U8并调试设置2. 用友U8借助cpolar实现企业远程办公2.1 在被控端电脑上&#xff0c;点击开始菜单栏&#xff0c;打开设置——系统2.2 找到远程桌面2.3 启用远程桌面 3. 安装cpolar内网穿透3.1 注册cpolar账号3.2 下载cpolar客户端 4. 获取远程桌面…

【MATLAB源码-第75期】基于模拟退火算法(SA)的栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 模拟退火算法是一种启发式优化算法&#xff0c;通常用于解决组合优化问题&#xff0c;例如旅行商问题和图着色问题。它模拟了固体材料在退火过程中逐渐冷却达到稳定状态的行为&#xff0c;以寻找问题的全局最优解。 以下是模…

Hadoop原理,HDFS架构,MapReduce原理

Hadoop原理&#xff0c;HDFS架构&#xff0c;MapReduce原理 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c…

postswigger 靶场(CSRF)攻略-- 1.没有防御措施的 CSRF 漏洞

靶场地址&#xff1a; What is CSRF (Cross-site request forgery)? Tutorial & Examples | Web Security Academy (portswigger.net)https://portswigger.net/web-security/csrf 没有防御措施的 CSRF 漏洞 题目中已告知易受攻击的是电子邮件的更改功能&#xff0c;而目…

Oracle Primavera Unifier 23.10 新特征

根据官方的说法&#xff0c;Unifier 23.7 ~ 23.9 更多为对功能bug的修复&#xff0c;以下将对23.10进行重点介绍 Cost Sheets Cost Sheets Support Conditional Formatting Conditional formatting of table data is now supported in cost sheets with features such as ce…