当前位置: 首页 > 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.dtcms.com/a/298994.html

相关文章:

  • 【Java EE初阶 --- 网络原理】传输层---UDP/TCP协议
  • Spring boot Grafana优秀的监控模板
  • C++:list(2)list的模拟实现
  • 高并发微服务限流算法方案对比与实践指南
  • 【音视频协议篇】WebRTC 快速入门
  • 嵌入式——C语言:指针②
  • Kotlin线程同步
  • TCP/IP 网络编程面试题及解答
  • 数智管理学(三十九)
  • train_model_components ——组件模型的灵感,灵感
  • PYTHON从入门到实践-15数据可视化
  • 震网(Stuxnet):打开潘多拉魔盒的数字幽灵
  • Android ADB命令之内存统计与分析
  • C++对象模型
  • CH341 Linux驱动 没有 /dev/ttyCH341USB0
  • 前端模块化开发实战指南
  • kafka中生产者的数据分发策略
  • starrocks官网docker部署mysql无法连接
  • 影刀RPA_Temu关键词取数_源码解读
  • RK3568笔记九十三:基于RKNN Lite的YOLOv5目标检测
  • 高性能网络DPDK、RDMA、XDP初探
  • VTK交互——ClientData
  • Java程序员学从0学AI(六)
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现轮船检测识别(C#代码UI界面版)
  • 热传导问题Matlab有限元编程 :工业级热仿真核心技术-搭建热传导求解器【含案例源码】
  • CSS3知识补充
  • 【企业架构】TOGAF概念之二
  • 基于深度学习的图像分类:使用Capsule Networks实现高效分类
  • 【Linux手册】操作系统如何管理存储在外设上的文件
  • 用 FFmpeg 把视频输出为图片序列