纯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.rhkb.cn/news/190398.html

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

相关文章

【Pytest】跳过执行之@pytest.mark.skip()详解

一、skip介绍及运用 在我们自动化测试过程中&#xff0c;经常会遇到功能阻塞、功能未实现、环境等一系列外部因素问题导致的一些用例执行不了&#xff0c;这时我们就可以用到跳过skip用例&#xff0c;如果我们注释掉或删除掉&#xff0c;后面还要进行恢复操作。 1、skip跳过成…

Spring IOC - Bean的生命周期之实例化

在Spring启动流程文章中讲到&#xff0c;容器的初始化是从refresh方法开始的&#xff0c;其在初始化的过程中会调用finishBeanFactoryInitialization方法。 而在该方法中则会调用DefaultListableBeanFactory#preInstantiateSingletons方法&#xff0c;该方法的核心作用是初始化…

元核云亮相金博会,智能质检助力金融合规

11月初&#xff0c;第五届中新&#xff08;苏州&#xff09;数字金融应用博览会&#xff5c;2023金融科技大会在苏州国际博览中心举办&#xff0c;围绕金融科技发展热点领域及金融行业信息科技领域重点工作&#xff0c;分享优秀实践经验&#xff0c;探讨数字化转型路径与未来发…

蓝桥杯每日一题2023.11.8

题目描述 题目分析 对于输入的abc我们可以以a为年也可以以c为年&#xff0c;将abc,cab,cba这三种情况进行判断合法性即可&#xff0c;注意需要排序去重&#xff0c;所以考虑使用set 此处为纯模拟的写法&#xff0c;但使用循环代码会更加简洁。 方法一&#xff1a; #include&…

物联网AI MicroPython学习之语法 network网络配置模块

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; network介绍 模块功能&#xff1a; 用于管理Wi-Fi和以太网的网络模块参考用法&#xff1a; import network import time nic network.WLAN(network.STA_IF) nic.active(True) if not nic.isconnected():…

SplayTree高分测试用例

测试用例结果展示 覆盖率 变异得分 测试注意点 从SplayTree测起&#xff0c;然后再测SubSplayTree&#xff0c;因为前者调用后者。SplaySubTree的remove方法大部分内容需要通过反射才能测到。value和index在SplayTree当中都不是唯一的。一个index可能对应多个value。 不足之…

【Maven教程】(十):使用 Hudson 进行持续集成—— 从Hudson的安装到任务创建 ~

Maven 使用 Hudson 进行持续集成 1️⃣ 持续集成的作用、过程和优势2️⃣ Hudson 简介与安装3️⃣ 准备 Subversion 仓库4️⃣ Hudson 的基本系统设置5️⃣ 创建 Hudson 任务5.1 Hudson 任务的基本配置5.2 Hudson 任务的源码仓库配置5.3 Hudson 任务的构建触发配置5.4 Hudson …

代码随想录 Day43 动态规划11 LeetCode T309 买卖股票的最佳时期含冷冻期 T714买卖股票的最佳时机含手续费

LeetCode T309 买卖股票的最佳时机含冷冻期 题目链接:309. 买卖股票的最佳时机含冷冻期 - 力扣&#xff08;LeetCode&#xff09; 题目思路: 这题其实就是将卖出的状态拆分成三个状态 1.前两天就卖出并一直保持卖出的状态 2.今天卖出的状态 3.今天是冷冻期的状态 当然还有一个…

Sprint Boot 学习路线 6

测试 Spring提供了一组测试工具&#xff0c;可以轻松地测试Spring应用程序的各个组件&#xff0c;包括控制器、服务、存储库和其他组件。它具有丰富的测试注释、实用程序类和其他功能&#xff0c;以帮助进行单元测试、集成测试等。 JPA测试 Spring JPA&#xff08;Java Pers…

DBever连接PG库

一、简介 DBeaver是一种通用数据库管理工具&#xff0c;适用于需要以专业方式使用数据的每个人&#xff1b;适用于开发人员&#xff0c;数据库管理员&#xff0c;分析师和所有需要使用数据库的人员的 免费(DBeaver Community) 的多平台数据库工具&#xff0c;支持 Windows、Li…

postswigger 靶场(CSRF)攻略-- 2.令牌验证

靶场地址&#xff1a; What is CSRF (Cross-site request forgery)? Tutorial & Examples | Web Security Academy (portswigger.net)https://portswigger.net/web-security/csrf 令牌(token)验证取决于请求方法 题目中已告知易受攻击的是电子邮件的更改功能&#xff0…

基因检测技术的发展与创新:安全文件数据传输的重要作用

基因是生命的密码&#xff0c;它决定了我们的身体特征、健康状况、疾病风险等。随着基因检测技术的高速发展&#xff0c;我们可以通过对基因进行测序、分析和解读&#xff0c;更深入地认识自己&#xff0c;预防和治疗各种遗传性疾病&#xff0c;甚至实现个性化医疗和精准健康管…

网络编程 初探windows编程

目录 一、什么是Winodws编程 二、开发环境搭建以及如何学习 三、VA助手安装 四、第一个Win32程序 五、窗口类句柄/窗口类对象 六、Winodws消息循环机制 七、Windows数据类型 一、什么是Winodws编程 Windows 编程指的是在 Microsoft Windows 操作系统上进行软件开发的过…

在报错中学python something

这里写目录标题 动手学深度学习pandas完整代码数据处理TypeError: can only concatenate str (not "int") to str&#xff08;fillna填补缺失值&#xff09; 创建文件夹学习这个数据分组get_dummies实现one hot encode 动手学深度学习pandas完整代码 import osimpor…

CCF CSP认证历年题目自练Day45

这几天搞泰迪杯数据分析技能赛去了。等拿国奖了就出一期关于泰迪杯的。 题目 试题编号&#xff1a; 201703-3 试题名称&#xff1a; Markdown 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 256.0MB 问题描述&#xff1a; 问题描述   Markdown 是一种很流行的轻量级标记…

怎么设置代理IP进行网络爬取呢?代理访问网络如何设置?

在如今网络爬虫广泛应用的年代&#xff0c;很多时候我们都会遇到需要使用代理IP进行网络爬取的情况。代理IP可以帮助我们隐藏真实的IP地址&#xff0c;从而保护我们的隐私和安全。那么&#xff0c;怎么设置代理IP进行网络爬取呢&#xff1f;代理访问网络如何设置&#xff1f;下…

如何使用CORS和CSP保护前端应用程序安全

前端应用在提供无缝用户体验方面起着核心作用。在当今互联网的环境中&#xff0c;第三方集成和API的普及使得确保强大的安全性至关重要。安全漏洞可能导致数据盗窃、未经授权访问以及品牌声誉受损。本文将向您展示如何使用CORS和CSP为您的网页增加安全性。 嗨&#xff0c;大家好…

08.Diffusion Model数学原理分析(下)

文章目录 denoising matching term σ t z \sigma_tz σt​z的猜想Diffusion Model for SpeechDiffusion Model for TextMask-Predict 部分截图来自原课程视频《2023李宏毅最新生成式AI教程》&#xff0c;B站自行搜索。 书接上文。 denoising matching term E q ( x t ∣ x 0 …

极狐GitLab CI 助力 .Net 项目研发效率和质量双提升

目录 .NET nuget 自动生成测试包&#xff08;prerelease&#xff09;版本号 .NET 版本号规范 持续集成自动打包 持续集成自动修改版本号 .NET 行级增量代码规范——拯救老项目 本地全量代码规范 行级增量代码规范 很多团队或开发者都会使用 C#、VB 等语言开发 .Net 应用…

02-瑞吉外卖员工表的增删改查

添加员工信息 执行流程 第一步: 用户点击添加员工按钮跳转到add.html页面,然后在页面中输入要添加的员工的信息 第二步: 用户点击保存按钮发送Ajax请求将用户输入的员工信息以json的格式提交到服务端 第三步: 服务端Controller接收页面提交的json格式的数据并转化为java对象…