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

[C/C++]数据结构 栈和队列()

一:栈

1.1 栈的概念及结构

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

  •         压栈:栈的插入操作叫做进栈/压栈/入栈,将数据插入栈顶
  •         出栈:栈的删除操作也叫出栈,出数据也在栈顶

1.2栈的实现

        栈的实现一般可以用数组或者链表实现,相对而言数组的结构更优一点,因为数组在尾上插入数据的代价更小 ,链表则需从头遍历到尾

支持动态增长的栈:

typedef int STDataType;
typedef struct stack
{int* a;int top;  //用于维护栈顶int capacity;//栈的容量
}ST;

常用功能接口:

//栈的初始化
void STInit(ST* ps);
//压栈
void STPush(ST* ps,STDataType x);
//出栈
void STPop(ST* ps);
//取栈顶元素
STDataType STTop(ST* ps);
//判断栈是否为空
bool STEmpty(ST* ps);
//求栈的大小
int STSize(ST* ps);
//摧毁栈
void STDestroy(ST* ps);

1.栈的初始化

        要注意栈结构中的top可以初始化为0也可以初始化为-1,这里以初始化为0为例

  • 初始化为0: top的值可以表示栈元素的个数
  • top初始化位-1: top指向栈顶元素
void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}

2.压栈

void STPush(ST* ps, STDataType x)
{assert(ps);//扩容if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* ret = (STDataType*)realloc(ps->a,sizeof(STDataType)*newcapacity);if (ret == NULL){perror("realloc");return;}ps->a = ret;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}

3.出栈

void STPop(ST* ps)
{assert(ps); assert(ps->top); //确保栈中还有元素ps->top--;
}

4.取栈顶元素

STDataType STTop(ST* ps)
{assert(ps);assert(ps->top);return ps->a[ps->top - 1];
}

5.判断栈是否为空

bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

6.求栈的大小

int STSize(ST* ps)
{assert(ps);return ps->top;
}

7.摧毁栈

void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a == NULL;ps->top = ps->capacity = 0;
}

二. 队列

2.1 队列的概念及结构

        队列只允许一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特点,进行插入操作的一端称为队尾,进行删除操作的一端称为队头.

2.2 队列的实现

        队列也可以用数组和链表的结构实现,使用链表的结构实现会更优一点,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低.

队列的结构:

typedef int QDataType;//链式结构:表示队列
typedef struct QueueNode {QDataType x;struct QueueNode* next;
}Node;//队列的结构:队头和队尾分别用head和tail指针维护
typedef struct Queue
{Node* head;Node* tail;int size;
}Queue;

接口:

//队列的初始化
void QueueInit(Queue* ps);
//入队列
void QueuePush(Queue* ps,QDataType x);
//出队列
void QueuePop(Queue* ps);
//判断队列是否为空
bool QueueEmpty(Queue* ps);
//取队头元素
QDataType QueueFront(Queue* ps);
//取队尾元素
QDataType QueueTail(Queue* ps);
//求队列大小
int QueueSize(Queue* ps);
//摧毁队列
void QueueDestory(Queue* ps);

1.队列的初始化


void QueueInit(Queue* ps)
{assert(ps);ps->head = ps->tail = NULL;ps->size = 0;
}

2.入队列

void QueuePush(Queue* ps, QDataType x)
{assert(ps);//创建新节点Node* newnode = (Node*)malloc(sizeof(Node));if (newnode == NULL){perror("malloc");return;}newnode->next = NULL;newnode->x = x;//尾插if (ps->tail == NULL){ps->head = ps->tail = newnode;}else{ps->tail->next = newnode;ps->tail = ps->tail->next;}ps->size++;
}

3.出队列

void QueuePop(Queue* ps)
{assert(ps);assert(ps->head);if (ps->head->next == NULL){ps->head = ps->tail = NULL;}else{Node* next = ps->head->next;free(ps->head);ps->head = next;}ps->size--;
}

4.判断队列是否为空

bool QueueEmpty(Queue* ps)
{assert(ps);return ps->tail == NULL;
}

5.取队头元素

QDataType QueueFront(Queue* ps)
{assert(ps);assert(ps->head);return ps->head->x;
}

6.取队尾元素

QDataType QueueTail(Queue* ps)
{assert(ps);assert(ps->tail);return ps->tail->x;
}

7.求队列大小

int QueueSize(Queue* ps)
{assert(ps);return ps->size;
}

8.摧毁队列

void QueueDestory(Queue* ps)
{assert(ps);Node* cur = ps->head;while (cur){Node* next = cur->next;free(cur);cur = next;}ps->head=ps->tail = NULL;
}


 

相关文章:

  • Jenkinsfile+Dockerfile前端vue自动化部署
  • 数据结构:红黑树讲解(C++)
  • 【数据结构】栈与队列面试题(C语言)
  • 矩阵运算_矩阵的协方差矩阵/两个矩阵的协方差矩阵_求解详细步骤示例
  • 机器学习第8天:SVM分类
  • 【论文阅读】A Survey on Video Diffusion Models
  • Linux--网络概念
  • ZJU Beamer学习手册(二)
  • 全志XR806基于http的无线ota功能实验
  • 创新研报|新业务发展是CEO推动企业增长的必要选择 – Mckinsey研究
  • 音视频项目—基于FFmpeg和SDL的音视频播放器解析(十)
  • android开发连接网络
  • Leetcode—141.环形链表【简单】
  • csapp深入理解计算机系统 bomb lab(1)phase_1
  • Redis数据的持久化
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • k个最大的数及变种小结
  • PV统计优化设计
  • Terraform入门 - 1. 安装Terraform
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 聊一聊前端的监控
  • 前嗅ForeSpider采集配置界面介绍
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • ​flutter 代码混淆
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • #Z2294. 打印树的直径
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • ${factoryList }后面有空格不影响
  • $refs 、$nextTic、动态组件、name的使用
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (3)nginx 配置(nginx.conf)
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (备忘)Java Map 遍历
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (三)docker:Dockerfile构建容器运行jar包
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .net mvc 获取url中controller和action
  • .NET Project Open Day(2011.11.13)
  • .net 使用ajax控件后如何调用前端脚本
  • .NetCore 如何动态路由
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .NET面试题(二)
  • @RequestBody的使用
  • [ C++ ] STL priority_queue(优先级队列)使用及其底层模拟实现,容器适配器,deque(双端队列)原理了解
  • [].slice.call()将类数组转化为真正的数组
  • [20180312]进程管理其中的SQL Server进程占用内存远远大于SQL server内部统计出来的内存...
  • [AndroidStudio]_[初级]_[修改虚拟设备镜像文件的存放位置]
  • [bzoj4010][HNOI2015]菜肴制作_贪心_拓扑排序
  • [CLickhouse] 学习小计