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

【数据结构初阶】--栈和队列(一)

 🔥个人主页:@草莓熊Lotso

🎬作者简介:C++研发方向学习者

📖个人专栏: 《C语言》 《数据结构与算法》《C语言刷题集》《Leetcode刷题指南》

⭐️人生格言:生活是默默的坚持,毅力是永久的享受。  

前言: 前面我们学习完了顺序表和链表,那么接下来我们会继续学习栈和队列的知识,还是和之前一样会完全实现一遍,有了前面的基础其实栈和队列的实现会轻松很多的


目录

一.栈的概念和结构

二.栈的初始化和销毁

 三.栈的入栈和出栈

入栈:

出栈:

四.取栈顶元素和获取栈中有效元素个数

取栈顶元素:

获取栈中元素个数:

 五.代码展现

Stack.h:

Stack.c:

test.c:


一.栈的概念和结构

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

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

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

 我们可以把栈的结构想成水杯,杯底是封闭的,接水和倒水都在杯顶

--我们栈的实现一般可以使用数据或者链表实现,相对而言数组的结构实现更优一些。我们将数组的尾部作为栈顶,数组首部作为栈底,数组的尾部操作时间复杂度都是O(1)。其实链表使用头部操作也可以,但是综合空间来说使用数组更优一点

--我们先来看下栈的结构的定义

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 STDestory(ST* ps)
{if (ps->arr)free(ps->arr);ps->arr = NULL;ps->top = 0;ps->capacity = 0;
}

重点提示:

栈的创建和销毁都是跟顺序表差不多的,没有很大的区别,为了区分我们把size这里定义的是top


 三.栈的入栈和出栈

--栈的入栈和出栈操作我们实现起来也都很简单,我们直接来看看吧

入栈:

void STPush(ST* ps, STDataType x)
{assert(ps);//检查空间//空间不够就增容if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->arr, newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newcapacity;}//空间足够ps->arr[ps->top++] = x;
}

看到这些代码,大家应该都不会很陌生,跟顺序表一样,空间足够直接尾部插入一个数据,top++,空间不够就扩容,扩容操作和顺序表是一模一样,不是很了解的可以看下博主前面顺序表实现的博客

--在实现出栈之前,我们先要实现一个判空操作的接口

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

如果top为0,就证明了栈为空

出栈:

//出栈
void STPop(ST* ps)
{assert(!STEmpty(ps));ps->top--;
}

栈不为空,就直接ps->top--就ok了,不需要其它的操作,实现起来很方便  


四.取栈顶元素和获取栈中有效元素个数

 --取栈顶元素实现了之后,我们就可以在test.c中实现取栈顶元素,打印再出栈的操作了,可以观察一下我们栈的先进后出特性

取栈顶元素:

//取栈顶元素
STDataType STTop(ST* ps)
{assert(!STEmpty(ps));return 	ps->arr[ps->top - 1];;
}

注意这里取出来的一定是下标为ps->top-1的元素 

 test.c:

#include"stack.h"void test1()
{ST ps;STInit(&ps);//入栈STPush(&ps, 1);STPush(&ps, 2);STPush(&ps, 3);STPush(&ps, 4);while (!STEmpty(&ps)){//取栈顶元素,打印STDataType top = STTop(&ps);printf("%d ", top);//出栈STPop(&ps);}printf("\n");//销毁STDestory(&ps);
}int main()
{test1();
}

--测试完成,打印没有问题,先进的后出,退出码为0

获取栈中元素个数:

//求栈中有效数据个数
int STSize(ST* ps)
{assert(ps);return ps->top;
}

这个实现起来也是非常简单了,直接返回ps->top刚好就是有效元素个数 


 五.代码展现

Stack.h:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>typedef int STDataType;
typedef struct Stack
{STDataType* arr;int top;int capacity;
}ST;//初始化
void STInit(ST* ps);
//销毁
void STDestory(ST* ps);
//入栈
void STPush(ST* ps, STDataType x);
//出栈
void STPop(ST* ps);
//取栈顶元素
STDataType STTop(ST* ps);
//判空
bool STEmpty(ST* ps);
//求栈中有效数据个数
int STSize(ST* ps);

Stack.c:

#include"stack.h"//初始化
void STInit(ST* ps)
{ps->arr = NULL;ps->top = ps->capacity = 0;
}//销毁
void STDestory(ST* ps)
{if (ps->arr)free(ps->arr);ps->arr = NULL;ps->top = 0;ps->capacity = 0;
}//入栈
void STPush(ST* ps, STDataType x)
{assert(ps);//检查空间//空间不够就增容if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->arr, newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newcapacity;}//空间足够ps->arr[ps->top++] = x;
}//判空
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
//出栈
void STPop(ST* ps)
{assert(!STEmpty(ps));ps->top--;
}//取栈顶元素
STDataType STTop(ST* ps)
{assert(!STEmpty(ps));return 	ps->arr[ps->top - 1];;
}//求栈中有效数据个数
int STSize(ST* ps)
{assert(ps);return ps->top;
}

test.c:

#include"stack.h"void test1()
{ST ps;STInit(&ps);//入栈STPush(&ps, 1);STPush(&ps, 2);STPush(&ps, 3);STPush(&ps, 4);while (!STEmpty(&ps)){//取栈顶元素,打印STDataType top = STTop(&ps);printf("%d ", top);//出栈STPop(&ps);}printf("\n");//销毁STDestory(&ps);
}int main()
{test1();
}

往期回顾:

【数据结构初阶】--单链表(二)

【数据结构初阶】--双向链表(一)

【数据结构初阶】--双向链表(二)

结语:这篇博客我们完成了栈这个数据结构的实现,大家可以发现,有了前面的基础我们再来实现起来简直就是如鱼得水,很顺畅。那么我们在下篇博客中会继续队列这个数据结构的实现,如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持

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

相关文章:

  • 注意力机制介绍
  • 从链式协同到生态共生:制造业数智化供应链跃升之路
  • spring boot 项目如何使用jasypt加密
  • 【中文翻译】SmolVLA:面向低成本高效机器人的视觉-语言-动作模型
  • 认识自我的机器人:麻省理工学院基于视觉的系统让机器了解自身机体
  • 机器人芯片(腾讯元宝)
  • 《小白学习产品经理》第八章:方法论之马斯洛需求层次理论
  • 【JS】获取元素宽高(例如div)
  • 暑假算法训练.6
  • 单片机学习笔记.单总线one-wire协议(这里以普中开发板DS18B20为例)
  • SQL JOIN 全解析:用 `users` 与 `orders` 表彻底掌握内连接、左连接、右连接
  • PostgreSQL大数据集查询优化
  • 蓝桥杯51单片机
  • 第十四届蓝桥杯青少Scratch国赛真题——太空大战
  • 解决 NCCL 多节点通信问题:从 nranks 1 到 busbw 116 MB/s
  • 02-netty基础-java四种IO模型
  • 二、计算机网络技术——第3章:数据链路层
  • Yocto meta-toradex-security layer 使用 TI AM62 安全启动功能
  • vscode,cursor,Trae终端不能使用cnpm、npm、pnpm命令解决方案
  • QT RCC 文件
  • Hadoop调度器深度解析:FairScheduler与CapacityScheduler的优化策略
  • PHP获取淘宝拍立淘(以图搜图)API接口操作详解
  • Ext4文件系统全景解析
  • 【n8n教程笔记——工作流Workflow】文本课程(第一阶段)——1、导航编辑器界面(Navigating the editor UI)介绍
  • DOM编程全解析:操作、事件与存储实战指南
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现水下鱼类识别(C#代码,UI界面版)
  • 深入浅出Proxy与Reflect:从“黑中介“到“数据管家“的进阶之路
  • 【openssl生成自签证书】
  • Redis持久化-AOF
  • OpenCV 零基础到项目实战 | DAY 1:图像基础与核心操作