栈和队列的动态实现(C语言实现)

请添加图片描述

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿
🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
🌟🌟 追风赶月莫停留 🌟🌟
🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀
🌟🌟 平芜尽处是春山🌟🌟
🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅

🍋栈和队列

  • 🍑栈
    • 🍍栈的含义
    • 🍍栈的结构
    • 🍍栈的实现
      • 🍌栈的补充条件
      • 🍌初始化栈
      • 🍌入栈
      • 🍌出栈
      • 🍌获取栈顶元素
      • 🍌获取栈中有效元素的个数
      • 🍌检查栈是否为空
      • 🍌销毁栈
    • 🍍栈的整体代码的实现
  • 🍑队列
    • 🍍队列的含义
    • 🍍队列的结构
    • 🍍队列的实现
      • 🍌队列的补充条件
      • 🍌初始化队列
      • 🍌队尾入队列
      • 🍌队头出队列
      • 🍌获取队列头部元素
      • 🍌获取队列队尾元素
      • 🍌获取队列中有效元素个数
      • 🍌检测队列是否为空
      • 🍌 销毁队列
    • 🍍队列的整体代码的实现

🍑栈

🍍栈的含义

栈是一种特殊类型的线性表,它的特点是仅允许在其一端进行插入(压入)和删除(弹出)操作。这一端被称为栈顶,而相对的另一端则被称为栈底。栈通常遵循“后进先出”(LIFO)的原则,意味着新加入的元素总是位于栈顶,而要访问或移除的元素必须从前部移除。

🍍栈的结构

在这里插入图片描述

栈的结构就是如图片中的形容的类似,满足先进后出

🍍栈的实现

🍌栈的补充条件

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int STDatetype;//方便后续数据不只是int,也可以方便的换其他类型typedef struct Stack//利用结构体来定义栈
{STDatetype* a;int top; int capacity;
}ST;
int main()
{ST st;STInia(&st);STPush(&st, 1);STPush(&st, 2);STPush(&st, 3);STPush(&st, 4);STPush(&st, 5);while (!STEmpty(&st)){printf("%d ", STTop(&st));STPop(&st);}printf("\n");STDestroy(&st);return 0;
}

🍌初始化栈

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

🍌入栈

void STPush(ST* ps, STDatetype x)
{assert(ps);if (ps->top == ps->capacity){int newcapacity = 0;if (ps->capacity == 0){newcapacity = 2;}else{newcapacity = newcapacity * 2;}STDatetype* tem = (STDatetype*)realloc(ps->a, sizeof(STDatetype) * newcapacity);if (tem == NULL){perror("realloc  fail");exit(-1);}ps->a = tem;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}

(1)之所以在这里不用malloc创建空间,是因为后面还要用realloc进行扩容,所以就直接用realloc进行空间的创建。
(2)在ps->top和ps->capacity相等时进行扩容,在这里进行了判断,有两种情况。第一种是ps->capacity等于0,那就得先创建空间。第二种是ps->capacity不为0,就直接扩容为原来2倍的空间

🍌出栈

void STPop(ST* ps)
{assert(ps);assert(ps->top > 0);//判断数据是否为空(ps->top)--;}

🍌获取栈顶元素

STDatetype STTop(ST* ps)
{assert(ps);assert(ps->top > 0);//判断是否为空return ps->a[ps->top - 1];
}

🍌获取栈中有效元素的个数

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

在栈中数据个数其实就是ps->top

🍌检查栈是否为空

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

如果为空就返回1,不为空就返回0

🍌销毁栈

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

🍍栈的整体代码的实现

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int STDatetype;typedef struct Stack
{STDatetype* a;int top; int capacity;
}ST;void STInia(ST* ps)
{assert(ps);ps->top = ps->capacity = 0;ps->a = NULL;
}void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}void STPush(ST* ps, STDatetype x)
{assert(ps);if (ps->top == ps->capacity){int newcapacity = 0;if (ps->capacity == 0){newcapacity = 2;}else{newcapacity = ps->capacity * 2;}STDatetype* tem = (STDatetype*)realloc(ps->a, sizeof(STDatetype) * newcapacity);if (tem == NULL){perror("realloc  fail");exit(-1);}ps->a = tem;ps->capacity = newcapacity;}ps->a[ps->top] = x;(ps->top)++;
}void STPop(ST* ps)
{assert(ps);assert(ps->top > 0);(ps->top)--;}int STSize(ST* ps)
{assert(ps);return ps->top;
}bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}STDatetype STTop(ST* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];
}int main()
{ST st;STInia(&st);STPush(&st, 1);STPush(&st, 2);STPush(&st, 3);STPush(&st, 4);STPush(&st, 5);while (!STEmpty(&st)){printf("%d ", STTop(&st));STPop(&st);}printf("\n");STDestroy(&st);return 0;
}

🍑队列

🍍队列的含义

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

🍍队列的结构

在这里插入图片描述

队列和栈有点类似,只不过栈是先进后出,而队列是先进先出

🍍队列的实现

🍌队列的补充条件


#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int QDatetype;
typedef struct QueueNode
{struct QueueNode* next;QDatetype date;
}QNode;typedef struct Queue
{QNode* head;QNode* tail;int size;
}Que;
///
int main()
{Que qq;QueueInia(&qq);QueuePush(&qq, 1);QueuePush(&qq, 2);QueuePush(&qq, 3);QueuePush(&qq, 4);while (!QueueEmpty(&qq)){printf("%d ", QueueFront(&qq));QueuePop(&qq);}printf("\n");return 0;
}

在这个队列中,我是采用了单链表(单向不循环)的结构来实现队列,所以再这里要注意头可能是空指针的问题,在前面我介绍单链表的时候是利用二级指针解决这个问题,而在这里是采用了新的方法,也就是结构体指针,把头和尾重新用一个结构体来定义

🍌初始化队列

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

🍌队尾入队列

void QueuePush(Que* ps, QDatetype x)
{assert(ps);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc  fail");exit(-1);}newnode->next = NULL;newnode->date = x;if (ps->tail == NULL){ps->head = ps->tail = newnode;}else{ps->tail->next = newnode;ps->tail = newnode;}(ps->size)++;
}

🍌队头出队列

void QueuePop(Que* ps)
{assert(ps);assert(ps->size > 0);if (ps->head->next == NULL){free(ps->head);ps->head = ps->tail = NULL;}else{QNode* cur = ps->head->next;free(ps->head);ps->head = cur;}(ps->size)--;
}

🍌获取队列头部元素

QDatetype QueueFront(Que* ps)
{assert(ps);assert(!QueueEmpty(ps));return ps->head->date;
}

🍌获取队列队尾元素

QDatetype QueueBake(Que* ps)
{assert(ps);assert(!QueueEmpty(ps));return ps->tail->date;
}

🍌获取队列中有效元素个数

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

🍌检测队列是否为空

bool QueueEmpty(Que* ps)
{assert(ps);return ps->head == NULL;
}

🍌 销毁队列

void QueueDestroy(Que* ps)
{assert(ps);QNode* cur = ps->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}ps->head = ps->tail = NULL;ps->size = 0;
}

🍍队列的整体代码的实现

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int QDatetype;
typedef struct QueueNode
{struct QueueNode* next;QDatetype date;
}QNode;typedef struct Queue
{QNode* head;QNode* tail;int size;
}Que;void QueueInia(Que* ps)
{assert(ps);ps->head = NULL;ps->tail = NULL;ps->size = 0;
}bool QueueEmpty(Que* ps)
{assert(ps);return ps->head == NULL;
}void QueuePush(Que* ps, QDatetype x)
{assert(ps);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc  fail");exit(-1);}newnode->next = NULL;newnode->date = x;if (ps->tail == NULL){ps->head = ps->tail = newnode;}else{ps->tail->next = newnode;ps->tail = newnode;}(ps->size)++;
}void QueuePop(Que* ps)
{assert(ps);assert(ps->size > 0);if (ps->head->next == NULL){free(ps->head);ps->head = ps->tail = NULL;}else{QNode* cur = ps->head->next;free(ps->head);ps->head = cur;}(ps->size)--;
}QDatetype QueueFront(Que* ps)
{assert(ps);assert(!QueueEmpty(ps));return ps->head->date;
}QDatetype QueueBake(Que* ps)
{assert(ps);assert(!QueueEmpty(ps));return ps->tail->date;
}int QueueSize(Que* ps)
{assert(ps);return ps->size;
}void QueueDestroy(Que* ps)
{assert(ps);QNode* cur = ps->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}ps->head = ps->tail = NULL;ps->size = 0;
}int main()
{Que qq;QueueInia(&qq);QueuePush(&qq, 1);QueuePush(&qq, 2);QueuePush(&qq, 3);QueuePush(&qq, 4);while (!QueueEmpty(&qq)){printf("%d ", QueueFront(&qq));QueuePop(&qq);}printf("\n");return 0;
}

队列和栈我就不详细介绍了,如果有需要可以看我写的这篇博客:单链表

本期的内容就结束了,文章有错误的地方欢迎大家指正!!!

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/433995.html

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

相关文章

【LeetCode】112. 路径总和(简单)——代码随想录算法训练营Day18

题目链接&#xff1a;112. 路径总和 题目描述 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&…

ENVI下基于知识决策树提取地表覆盖信息

基于知识的决策树分类是基于遥感影像数据及其他空间数据,通过专家经验总结、简单的数学统计和归纳方法等,获得分类规则并进行遥感分类。分类规则易于理解,分类过程也符合人的认知过程,最大的特点是利用的多源数据。 决策树分类主要的工作是获取规则,本文介绍使用CART算法…

第17章_反射机制(理解Class类并获取Class实例,类的加载与ClassLoader的理解,反射的基本应用,读取注解信息,体会反射的动态性)

文章目录 第17章_反射机制本章专题与脉络1. 反射(Reflection)的概念1.1 反射的出现背景1.2 反射概述1.3 Java反射机制研究及应用1.4 反射相关的主要API1.5 反射的优缺点 2. 理解Class类并获取Class实例2.1 理解Class2.1.1 理论上2.1.2 内存结构上 2.2 获取Class类的实例(四种方…

每日一题——LeetCode1346.检查整数及其两倍数是否存在

方法一 循环查找 用indexOf查找每个元素的两倍是否存在在数组中&#xff0c;找到了就直接return true&#xff0c;循环结束还没找到就return false var checkIfExist function(arr) {for(let i0;i<arr.length;i){let index arr.indexOf(arr[i]*2)if(index>0 &&…

小土堆pytorch学习笔记003 | 下载数据集dataset 及报错处理

目录 1、下载数据集 2、展示数据集里面的内容 3、DataLoader 的使用 例子&#xff1a; 结果展示&#xff1a; 1、下载数据集 # 数据集import torchvisiontrain_set torchvision.datasets.CIFAR10(root"./test10_dataset", trainTrue, downloadTrue) test_set …

CAD-autolisp(二)——选择集、命令行设置对话框、符号表

目录 一、选择集1.1 选择集的创建1.2 选择集的编辑1.3 操作选择集 二、命令行设置对话框2.1 设置图层2.2 加载线型2.3 设置字体样式2.4 设置标注样式&#xff08;了解即可&#xff09; 三、符号表3.1 简介3.2 符号表查找3.2 符号表删改增 一、选择集 定义&#xff1a;批量选择…

基于springboot+vue的校园资料分享平台(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目背景…

VS如何打包环境

以VS2005为例子,做好的软件需要发给客户现场升级,有时候总是因为系统,环境变量不同导致软件不能正常运行打开,这也是程序员非常头疼的问题,今天我们就一起看下打包环境变量. 这样我们的环境变量就打包到setup中了,目标机台安装即可!!!

Neo4j 国内镜像下载与安装

Neo4j 5.x 简体中文版指南 社区版&#xff1a;https://neo4j.com/download-center/#community 链接地址&#xff08;Linux版&#xff09;&#xff1a;https://neo4j.com/artifact.php?nameneo4j-community-3.5.13-unix.tar.gz 链接地址&#xff08;Windows&#xff09;&#x…

Unity中URP下额外灯角度衰减

文章目录 前言一、额外灯中聚光灯的角度衰减二、AngleAttenuation函数的传入参数1、参数&#xff1a;spotDirection.xyz2、_AdditionalLightsSpotDir3、参数&#xff1a;lightDirection4、参数&#xff1a;distanceAndSpotAttenuation.zw5、_AdditionalLightsAttenuation 三、A…

6 模版

1.模板 1.1模板概念 就是提前准备好一些通用、可复用的东西。 C++提供两种模板机制:函数模板和类模板 1.2函数模板 1.2.1函数模板作用: 建立一个通用函数、其函数返回值类型和形参类型可以不具体确定,用一个虚拟的类型进行表示,和java的泛型一样。 语法: template&l…

spring-boot redis stream消息队列demo-及死信简单处理

Redis stream 是 Redis 5 引入的一种新的数据结构&#xff0c;它是一个高性能、高可靠性的消息队列&#xff0c;主要用于异步消息处理和流式数据处理。在此之前&#xff0c;想要使用 Redis 实现消息队列&#xff0c;通常可以使用例如&#xff1a;列表&#xff0c;有序集合、发布…