纯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.hqwc.cn/news/170668.html

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

相关文章

小程序day05

使用npm包 Vant Weapp 类似于前端boostrap和element ui那些的样式框架。 安装过程 注意:这里建议直接去看官网的安装过程。 vant-weapp版本最好也不要指定 在项目目录里面先输入npm init -y 初始化一个包管理配置文件: package.json 使用css变量定制vant主题样式&#xff0…

Halcon WPF 开发学习笔记(2):Halcon导出c#脚本和WPF初步开发

文章目录 前言HalconC#教学简单说明如何二开机器视觉如何二次开发Halcon导出Halcon脚本新建WPF项目&#xff0c;导入Halcon脚本和Halcon命名空间 前言 我目前搜了一下我了解的机器视觉软件&#xff0c;有如下特点 优点缺点兼容性教学视频(B站前三播放量)OpenCV开源&#xff0…

猫罐头怎么选择?精选的5款口碑好的猫罐头推荐!

猫罐头因其成分约80%为水分&#xff0c;对于不喜欢喝水的猫咪来说&#xff0c;正是可以用来补充水分的替代方案。 而近年来市面上也有越来越多讲究食用安全性的猫罐头&#xff0c;像是强调无添加多余加工品、或是不含谷物成分等的商品。但也因为种类过多&#xff0c;让铲屎官容…

Ansible角色定制实例

目录 角色定制&#xff1a;roles 角色定制实例&#xff1a;利用角色部署wordpress 1.在roles目录下生成对应的目录结构 2.定义配置文件 ①nginx ②php ③mysql ④定义剧本文件 ⑤启动服务 角色定制&#xff1a;roles 对于普通的剧本&#xff08;playbook&#xff09;有…

Jira Software Enterprise Crack

Jira Software Enterprise Crack Jira软件是为您的应用程序组中的每一个成员设计、监控和启动优秀软件的。 策略&#xff1a;生成用户故事和问题&#xff0c;策略冲刺&#xff0c;并在应用程序团队中分配任务。 跟踪&#xff1a;在具有绝对可见性的完整背景下&#xff0c;确定团…

Python---字典---dict

1、为什么需要字典 如果想要存储一个人的信息&#xff0c;姓名&#xff1a;Tom&#xff0c;年龄&#xff1a;20周岁&#xff0c;性别&#xff1a;男&#xff0c;如何快速存储。 person [Tom, 20, 男] 在日常生活中&#xff0c;姓名、年龄以及性别同属于一个人的基本特征。 但…

玩转硬件之Micro:bit的玩法(五)——垃圾分类

垃圾分类&#xff0c;为了美好的明天 垃圾是我们生活中不可避免的产物&#xff0c;每天都有大量的垃圾被丢弃&#xff0c;如果不加以处理&#xff0c;就会给环境和人类带来严重的危害。 垃圾分类是一种有效的垃圾管理方式&#xff0c;它是指按照一定的标准或规则&#xff0c;将…

从单服务设计看SLA保证

文章首发公众号&#xff1a;海天二路搬砖工 0. 引言 在微服务架构中&#xff0c;谈到SLA保证&#xff0c;我们更多是从宏观的角度来需求解决方案。比如&#xff0c;通过合理服务拆分来增加系统整体的可维护性&#xff1b;通过多实例部署来保证系统的灾备。但是单个服务是可靠…

AYIT-ACM实验室发展历程

AYIT-ACM简介 ACM协会为你的梦想插上翅膀。 本院ACM协会成立于2012年 2008年开始小规模参加河南省竞赛 2014年成功实现金牌零突破 指导老师&#xff1a;孙高飞老师 安阳工学院计算机科学与信息工程学院ACM队是一支优秀的队伍&#xff0c;一支充满活力与激情的队伍&am…

网络编程 初探windows编程

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

加速mvn下载seatunnel相关jar包

seatunnel安装的时候&#xff0c;居然要使用mvnw来下载jar包&#xff0c;而且是从https://repo.maven.apache.org 下载&#xff0c;速度及其缓慢&#xff0c;改用自己本地的mvn下载。 修改其安装插件相关脚本&#xff0c;复制install-plugin.sh重命名为install-plugin-mvn.sh …

Qt执行带参sql

//准备执行的sql语句&#xff0c;此为带参的sql语句query.prepare("update employee set Name:Name, Gender:Gender,Height:Height,"" Birthday:Birthday, Mobile:Mobile, Province:Province,"" City:City, Department:Department, Education:Educati…