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

数据结构 05(线性:栈和队列)

目录

概念与结构

栈的结构

初始化与销毁

入栈

出栈

取栈顶元素

取元素个数

整体实现

Stack.h

Stack.c

队列

概念与结构

队列的结构

初始化与销毁

入队

出队

取队头和队尾元素

取元素个数

整体实现

Queue.h

Queue.c


概念与结构

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

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

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

这里使用数组来实现栈,入栈出栈的时间复杂度都是 O(1) 。

栈的结构

栈和顺序表很像,把顺序表的size改为top。

typedef int STDataType;
typedef struct Stack
{STDataType* arr;int top;             //栈顶int capacity;
}ST;

初始化与销毁

void STInit(ST* ps)
{ps->arr = NULL;ps->top = ps->capacity = 0;
}void STDestroy(ST* ps)
{if (ps->arr)free(ps->arr);ps->arr = NULL;ps->top = ps->capacity = 0;
}

入栈

就像顺序表的尾插,入栈也一样

void StackPush(ST* ps, STDataType x)
{assert(ps);if (ps->capacity == ps->top){int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* newarr = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));if (newarr == NULL){perror("realloc fail!");exit(1);}ps->arr = newarr;}ps->arr[ps->top] = x;ps->top++;
}

出栈

bool StackEmpty(ST* ps)        //返回bool型判断
{assert(ps);return ps->top == 0;
}void StackPop(ST* ps)          //出栈
{assert(!StackEmpty(ps));--ps->top;
}

取栈顶元素

STDataType StackTop(ST* ps)
{assert(!StackEmpty(ps));return ps->arr[ps->top - 1];   // ps->top - 1
}

取元素个数

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

整体实现

Stack.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int STDataType;
typedef struct Stack
{STDataType* arr;int top;int capacity;
}ST;void STInit(ST* ps);
void STDestroy(ST* ps);
void StackPush(ST* ps, STDataType x);
void StackPop(ST* ps);
STDataType StackTop(ST* ps);
int STSize(ST* ps);
bool StackEmpty(ST* ps);

Stack.c

#include"Stack.h"void STInit(ST* ps)
{ps->arr = NULL;ps->top = ps->capacity = 0;
}void STDestroy(ST* ps)
{if (ps->arr)free(ps->arr);ps->arr = NULL;ps->top = ps->capacity = 0;
}void StackPush(ST* ps, STDataType x)
{assert(ps);if (ps->capacity == ps->top){int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* newarr = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));if (newarr == NULL){perror("realloc fail!");exit(1);}ps->arr = newarr;}ps->arr[ps->top] = x;ps->top++;
}bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}void StackPop(ST* ps)
{assert(!StackEmpty(ps));--ps->top;
}STDataType StackTop(ST* ps)
{assert(!StackEmpty(ps));return ps->arr[ps->top - 1];
}int STSize(ST* ps)
{assert(ps);return ps->top;
}

队列

概念与结构

概念:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO。

入队列:进行插入操作的一端称为队尾。

出队列:进行删除操作的一端称为队头。

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

队列的结构

为了追求更高的效率,这里创建两个结构体,一个为队列本体,一个为队列的结点。

typedef int QDataType;typedef struct QueueNode
{QDataType data;struct QueueNode* next;
}QueueNode;typedef struct Queue
{QueueNode* phead;QueueNode* ptail;int size;             //在数据多时,为了更好的知道队列内有多少元素,多
}Queue;                   //创建一个size来记录队列内元素的数量。

初始化与销毁

void QueueInit(Queue* pq)
{assert(pq);pq->phead = pq->ptail = NULL;pq->size = 0;
}void QueueDestroy(Queue* pq)
{assert(pq);QueueNode* pcur = pq->phead;while (pcur){QueueNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = pq->ptail = NULL;
}

入队

void QueuePush(Queue* pq,QDataType x)
{assert(pq);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = NULL;if (pq->phead == NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}

出队

bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == 0;
}void QueuePop(Queue* pq)
{assert(!QueueEmpty(pq));if (pq->phead == pq->ptail){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QueueNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}

取队头和队尾元素

QDataType QueueFront(Queue* pq)
{assert(!QueueEmpty(pq));return pq->phead->data;
}QDataType QueueBack(Queue* pq)
{assert(!QueueEmpty(pq));return pq->ptail->data;
}

取元素个数

int QueueSize(Queue* pq)
{//int size = 0;//QueueNode* pcur = pq->phead;//while (pcur)//{//	++size;//	pcur = pcur->next;//}//return size;return pq->size;
}

整体实现

Queue.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int QDataType;typedef struct QueueNode
{QDataType data;struct QueueNode* next;
}QueueNode;typedef struct Queue
{QueueNode* phead;QueueNode* ptail;int size;
}Queue;void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
int QueueSize(Queue* pq);

Queue.c

#define _CRT_SECURE_NO_WARNINGS
#include"Queue.h"void QueueInit(Queue* pq)
{assert(pq);pq->phead = pq->ptail = NULL;pq->size = 0;
}void QueueDestroy(Queue* pq)
{assert(pq);QueueNode* pcur = pq->phead;while (pcur){QueueNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = pq->ptail = NULL;
}void QueuePush(Queue* pq,QDataType x)
{assert(pq);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = NULL;if (pq->phead == NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == 0;
}void QueuePop(Queue* pq)
{assert(!QueueEmpty(pq));if (pq->phead == pq->ptail){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QueueNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}QDataType QueueFront(Queue* pq)
{assert(!QueueEmpty(pq));return pq->phead->data;
}QDataType QueueBack(Queue* pq)
{assert(!QueueEmpty(pq));return pq->ptail->data;
}int QueueSize(Queue* pq)
{//int size = 0;//QueueNode* pcur = pq->phead;//while (pcur)//{//	++size;//	pcur = pcur->next;//}//return size;return pq->size;
}

http://www.dtcms.com/a/395810.html

相关文章:

  • RAG系统嵌入模型怎么选?选型策略和踩坑指南
  • 机器学习 vs. 动力学模型,Ai2 最新研究:仅需 2 分钟,ACE2 可完成一次 4 个月季节预报
  • RNN循环神经网络详解
  • 【Nginx开荒攻略】深入解析Nginx进程管理与信号控制:从原理到实战
  • MySQL与Redis面试问题详解
  • 鸿蒙Next IPC Kit详解:构建高效进程间通信的完整指南
  • 【开题答辩全过程】以 基于springboot的高校疫情防控系统为例,包含答辩的问题和答案
  • Centos7 命令行使用nmcli重置网络配置
  • 如何计算sequence粒度的负载均衡损失
  • 学财税大数据应用,需要考CPA/税务师吗?
  • RAG全栈技术——文档加载器
  • 如何理解Service Mesh(服务网格)
  • android9适配camera gc02m1
  • 【十天成长计划】BoostKit初级班 开班啦!——陪伴式学习,阶梯式成长
  • 【图文详解】强化学习核心框架、数学基础、分类、应用场景
  • Rust简介
  • golang和rust内存分配策略
  • 简历项目之无人机图像目标识别
  • pantherx2 armbian librga-rockchip librga.so 编译安装方法
  • 【精品资料鉴赏】189页工程车辆集团数字化转型SAP解决方案
  • 算法 --- 多源 BFS
  • 15.Linux 硬盘分区管理
  • 2.UE-准备环境(二)-下载虚幻引擎源码和搞成vs项目并使用vs打开
  • G-Star公益行获评CCF优秀技术公益案例,用开源技术传递善意
  • 文化赋能・创意西宁 西宁传媒行业创业发展沙龙成功举办 探索本土企业升级新路径
  • TDengine 与 MYSQL 的差异总结
  • Mysql杂志(二十一)——Hash索引和二叉搜索树、AVL树
  • 什么是类的实例化
  • 西门子 S7-200 SMART PLC 实操案例:中断程序的灵活应用定时中断实现模拟量滤波(下)
  • STM32FreeRtos入门(二)——创建第一个多任务程序