当前位置: 首页 > news >正文

【数据结构】栈和队列的实现

目录

1 栈的概念和结构

2 栈的实现 

2.1 Stack.h文件

2.2 Stack.c文件

2.3 test.c文件

3 队列的概念及结构 

4 队列的实现 

4.1 Queue.h文件

4.2 Queue.c文件

4.3 test.c文件 


1 栈的概念和结构

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

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

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

2 栈的实现 

栈的实现一般可以用数组或者链表实现,相对而言数组的实现更优一些。数组在尾上插入数据的代价比较小。本文采用数组实现的方法。

 栈的实现需要创建一个头文件Stack.h,一个源文件Stack.c和一个测试文件test.c,用来测试功能。

2.1 Stack.h文件

#pragma once#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
typedef int STDataType;
typedef struct Stack
{STDataType* arr;int top;//指向栈顶元素的下一个位置int capacity;//容量
}ST;//栈的初始化
void STInit(ST* pst);
//插入数据(入栈)
void STPush(ST* pst, STDataType x);
//删除数据(出栈)
void STPop(ST* pst);
//获取栈顶数据
STDataType STTop(ST* pst);
//判断栈是否为空
bool STEmpty(ST* pst);
//获取栈里的数据个数
int STSize(ST* pst);
//栈的销毁
void STDestroy(ST* pst);

2.2 Stack.c文件

#include "Stack.h"
//栈的初始化
void STInit(ST* pst)
{pst->arr = NULL;pst->capacity = 0;pst->top = 0;
}
//插入数据(入栈)
void STPush(ST* pst, STDataType x)
{assert(pst);//判断空间是否足够,不够就扩容if (pst->top == pst->capacity){int newcapacity = pst->capacity == 0 ? 4 : 2 * pst->capacity;STDataType* tmp = (STDataType*)realloc(pst->arr, sizeof(STDataType) * newcapacity);if (tmp == NULL){perror("realloc");exit(1);}pst->capacity = newcapacity;pst->arr = tmp;}//插入数据pst->arr[pst->top] = x;pst->top++;
}
//删除数据(出栈)
void STPop(ST* pst)
{assert(pst);assert(pst->top > 0);pst->top--;
}
//获取栈顶数据
STDataType STTop(ST* pst)
{assert(pst);assert(pst->top > 0);return pst->arr[pst->top - 1];
}
//判断栈是否为空
bool STEmpty(ST* pst)
{assert(pst);return pst->top == 0;
}
//获取栈里的数据个数
int STSize(ST* pst)
{assert(pst);return pst->top;
}
//栈的销毁
void STDestroy(ST* pst)
{free(pst->arr);pst->arr = NULL;pst->top = 0;pst->capacity = 0;
}

2.3 test.c文件

#include "Stack.h"
int main()
{ST s;STInit(&s);STPush(&s, 1);STPush(&s, 2);STPush(&s, 3);STPush(&s, 4);while (!STEmpty(&s)){printf("%d\n", STTop(&s));STPop(&s);}//printf("%d\n", STTop(&s));//STPop(&s);STDestroy(&s);return 0;
}

3 队列的概念及结构 

队列只允许在一端插入数据,在另一端进行删除数据操作的特殊线性表。队列中的数据元素遵循先进先出的原则。插入数据的一端称为队尾,进行删除操作的一端称为队头

4 队列的实现 

队列可以用数组和链表的结构实现,使用链表的结构实现更好一些,如果使用数组的结构,出队列在数组头上出数据,效率比较低。本文采用链表的结构实现。

实现队列需要创建一个头文件Queue.h,源文件Queue.c,测试文件test.c,用来测试功能。

4.1 Queue.h文件

#pragma once#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>typedef int QDataType;typedef struct QueueNode
{struct QueueNode* next;QDataType val;
}QNode;typedef struct Queue
{QNode* phead;//头指针QNode* ptail;//尾指针int size;//队列内数据个数
}Queue;//初始化
void QueueInit(Queue* pq);
//插入数据(队尾)
void QueuePush(Queue* pq, QDataType x);
//删除数据(队头)
void QueuePop(Queue* pq);
//取出队头数据
QDataType QueueFront(Queue* pq);
//取出队尾数据
QDataType QueueBack(Queue* pq);
//判空
bool QueueEmpty(Queue* pq);
//统计队列数据个数
int QueueSize(Queue* pq);
//销毁队列
void QueueDestroy(Queue* pq);

4.2 Queue.c文件

#include "Queue.h"
//初始化
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
//插入数据(队尾)
void QueuePush(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc");exit(1);}newnode->next = NULL;newnode->val = x;if (pq->ptail==NULL){pq->ptail = pq->phead = newnode;}else{pq->ptail->next = newnode;pq->ptail = pq->ptail->next;}pq->size++;
}
//删除数据(队头)
void QueuePop(Queue* pq)
{assert(pq);assert(pq->size != 0);if (pq->phead == pq->ptail){free(pq->phead);pq->phead = NULL;pq->ptail = NULL;}else{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}
//取出队头数据
QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->phead);return pq->phead->val;
}
//取出队尾数据
QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->ptail);return pq->ptail->val;
}
//判空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}
//销毁队列
void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}
//统计队列数据个数
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}

4.3 test.c文件 

#include "Queue.h"
int main()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}QueueDestroy(&q);return 0;
}

 以上就是栈和队列的结构和代码实现,是依据顺序表和链表的原理来实现栈和队列,感兴趣的可以查看我之前的顺序表和链表的文章,如果这篇文章对你有用,可以点点赞哦,你的支持就是我写下去的动力,后续会不断地分享知识。

http://www.lryc.cn/news/600612.html

相关文章:

  • 基于DataX的数据同步实战
  • 详解力扣高频SQL50题之1141. 查询近30天活跃用户数【简单】
  • STM32-定时器的基本定时/计数功能实现配置教程(寄存器版)
  • 手动开发一个串口调试工具(二):Qt 串口类基本认识与使用
  • ClickHouse高性能实时分析数据库-消费实时数据流(消费kafka)
  • 【Linux系统】理解硬件 | 引入文件系统
  • Kotlin线程同步
  • 高并发微服务限流算法方案对比与实践指南
  • 告别Vite脚手架局限!MixOne Beta测试招募:你的需求,我们来实现
  • 基于 ThinkPHP 开发的垂直化网址导航
  • 深入解析Hadoop如何实现数据可靠性:三副本策略、校验和验证与Pipeline复制
  • 使用Spring Boot创建Web项目
  • Java 大视界 -- Java 大数据在智能安防视频监控系统中的视频语义理解与智能检索进阶(365)
  • 【工程化】浅谈前端构建工具
  • nginx一个域名下部署多套前端项目
  • 机器学习特征工程详解:特征选择与降维(PCA)
  • NLua和C#交互
  • Flask input 和datalist结合
  • VTK交互——ImageClip
  • xLua和C#交互
  • 高性能网络DPDK、RDMA、XDP初探
  • 电子电气架构 --- 高阶智能驾驶对E/E架构的新要求
  • 工具 | 解决 VSCode 中的 Delete CR 问题
  • uniapp+vue3——通知栏标题纵向滚动切换
  • 全球化2.0 | 云轴科技ZStack亮相阿里云印尼国有企业CXO专家活动
  • 以太坊下一阶段的关键——隐私
  • DSP在CCS中实现双核在线仿真调试及下载的方法(以TMS320F28x为例)
  • 生产环境使用云服务器(centOS)部署和使用MongoDB
  • (React入门上手——指北指南学习(第一节)
  • docker 从主机复制文件到容器外进行编辑