数据结构-栈(带图)

目录

栈的概念

画图理解栈

栈的实现

fun.h

fun.c

main.c


栈的概念

栈(Stack)是一种基本的数据结构,其特点是只允许在同一端进行插入和删除操作,这一端被称为栈顶。遵循后进先出(Last In, First Out, LIFO)原则,即最后存入栈中的元素最先被取出。形象地讲,栈就像是生活中堆放盘子的架子,我们总是把新的盘子放在最上面,而需要拿盘子时也是从最上面开始拿。

生活中就有栈的一些例子比如这些图片:

栈的基本操作包括

  1. 压栈(Push):向栈顶添加一个元素。相当于在堆叠的顶部放入一个新的物品。
  2. 出栈(Pop):从栈顶移除一个元素,并可选择返回这个元素。这类似于从堆叠顶部移走最上面的物品。
  3. 查看栈顶元素(Peek/Top):获取栈顶的元素但不移除它,用于检查或获取栈顶的信息。
  4. 判断栈是否为空(IsEmpty):检查栈中是否有元素。
  5. 获取栈的大小(Size):返回栈中元素的数量

画图理解栈

首先我们栈有一个原理:先进后出,后进先出,于是我们得得到这么个图


开始压栈,压栈的同时我们的p指针也要同时往后面走


最总


出栈


依次出栈后

这里为什么会1 2 3 4压栈出栈后变成了4321?

其实正确的压栈出栈我们需要边压栈边出栈就不会出现这种情况了,所以我main函数中是这样写的

int main1() {Stack p;STInit(&p);//初始化栈StackPush(&p, 1);//压栈StackPop(&p);//出栈printf("%d\n", p.a[p.top]);StackPush(&p, 2);StackPop(&p);printf("%d\n", p.a[p.top]);StackPush(&p, 3);StackPop(&p);printf("%d\n", p.a[p.top]);	
}

栈的实现

接下来我们用代码实现栈,这里我用了三个文件,解析都在注释中

fun.h

这个文件里有我实现了栈的一些功能

#pragma once
//头文件
#include<stdlib.h>
#include<stdbool.h>
#include<stdio.h>
#include<assert.h>typedef int STDataType;
//栈的结构
typedef struct Stack
{STDataType* a;//指针int top;//栈顶int capacity;//容量
}Stack;// 初始化栈 
void StackInit(Stack* ps);
// 入栈 
void StackPush(Stack* ps, STDataType data);
// 出栈 
void StackPop(Stack* ps);
// 获取栈顶元素 
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数 
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps);
// 销毁栈 
void StackDestroy(Stack* ps);

fun.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"fun.h"//扩容函数
void Exp(Stack* p) {if (p->capacity == p->top){//利用三目运算来判断是否int New_cap = p->capacity == 0 ? 4 : p->capacity * 2;STDataType* tmp = (STDataType*)realloc(p->a, New_cap * sizeof(STDataType));if (tmp == NULL){assert("realloc");return;}//将开辟空间给给原来的变量p->a = tmp;p->capacity = New_cap;}
}//初始化
void StackInit(Stack* p) {assert(p);p->a = NULL;p->capacity = p->top = 0;
}
// 入栈 
void StackPush(Stack* p, STDataType data){assert(p);//判断空间Exp(p);//入栈p->a[p->top] = data;//入栈后栈顶向上移动p->top++;
}
//出栈
void StackPop(Stack* p) {assert(p);assert(p->top > 0);//确保不为空//判断是否元素是否为0,避免越界 /*if (p->top == 0){return;}*/p->top--;
}
// 获取栈顶元素 
STDataType StackTop(Stack* p) {//判断是否为0if (p->top == 0){return (STDataType)0;//由于返回类型是 STDataType,所以需要强制转换}return p->a[p->top - 1];
}
// 获取栈中有效元素个数 
int StackSize(Stack* p) {return p->top;}
//判空
bool StackEmpty(Stack* p) {// 使用逻辑非操作符(!)来检查栈顶指针(top)是否为0(即栈是否为空)// 如果top为0,说明栈中没有任何元素,因此栈是空的// 在C语言中,逻辑非操作符会将0转换为1(true),非0转换为0(false)// 所以当栈顶指针top为0时,!p->top的结果为true(非零值),表示栈为空// 反之,如果栈中有元素(top非0),则!p->top的结果为false(0),表示栈非空return !p->top;
}
// 销毁栈 
void StackDestroy(Stack* p) {if (p->a){free(p->a);p->a = NULL;p->capacity = p->top = 0;}
}

main.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"fun.h"
//
//int main1() {
//	Stack p;
//	STInit(&p);
//	StackPush(&p, 1);
//	StackPop(&p);
//	printf("%d\n", p.a[p.top]);
//	StackPush(&p, 2);
//	StackPop(&p);
//	printf("%d\n", p.a[p.top]);
//	StackPush(&p, 3);
//	StackPop(&p);
//	printf("%d\n", p.a[p.top]);
//	
//	
//}int main() { Stack s1;StackInit(&s1);StackPush(&s1, 1);StackPush(&s1, 2);printf("栈中元素个数:%d个\n", StackSize(&s1));while (!StackEmpty(&s1)){printf("%d\n", StackTop(&s1));StackPop(&s1);}printf("栈中元素个数:%d个", StackSize(&s1));StackDestroy(&s1);
}

这个数据结构比较简单,里面的很多方法,都是和顺序表差不多,不懂得铁铁可以去看一下我前面的博客

数据结构:顺序表-CSDN博客文章浏览阅读838次,点赞18次,收藏9次。数据是计算机科学中的基本概念,它代表了在计算机程序中处理的一切信息内容。https://blog.csdn.net/2302_78381559/article/details/137435691这边可能你还是不是很理解栈,我们可以试着做一道Leetcode的题,来感受一下栈

题的链接

20. 有效的括号 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/valid-parentheses/description/

我对这道题理解之后写的一篇博客,供大家观看

20. 有效的括号 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/valid-parentheses/description/

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

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

相关文章

【论文粗读|arXiv】GaSpCT: Gaussian Splatting for Novel CT Projection View Synthesis

Abstract 本文提出了一种新颖的视图合成和3D场景表示方法&#xff0c;用于为计算机断层扫描&#xff08;CT&#xff09;生成新的投影视图。 方法采用了Gaussian Splatting 框架&#xff0c;基于有限的2D图像投影集&#xff0c;无需运动结构&#xff08;SfM&#xff09;方法&am…

Swift 5.9 中 if 与 switch 语句简洁新语法让撸码更带劲

概览 在实际代码开发中&#xff0c;可能初学 Swift 语言的小伙伴们在撸码时最常用的得数 if 和 switch…case 条件选择语句了。不过在某些场景下它们显得略有那么一丢丢“矫揉造作”&#xff0c;还好从 Swift 5.9 开始苹果知趣的为其简化了语法且增强了它们的表现力。 在本篇…

Vitis HLS 学习笔记--优化本地存储器访问瓶颈

目录 1. 简介 2. 代码解析 2.1 原始代码 2.2 优化后 2.3 分析优化措施 3. 总结 1. 简介 在Vitis HLS中&#xff0c;实现II&#xff08;迭代间隔&#xff09; 1是提高循环执行效率的关键。II1意味着每个时钟周期都可以开始一个新的迭代&#xff0c;这是最理想的情况&…

HNCTF ——baby_python

H&NCTF 2024 官方WP (qq.com) OpCodes Pickle.jl (juliahub.com) nc之后 PS D:\ForCode\pythoncode\.idea> nc hnctf.yuanshen.life 33267 # Python 3.10.12 from pickle import loads main b"\x80\x04ctypes\nFunctionType\n(ctypes\nCodeType\n(I1\nI0\nI0\n…

【Vim】

一、什么是Vim&#xff1f; Vim 是一个历史悠久的文本编辑器&#xff0c;可以追溯到 qed。 Bram Moolenaar 于 1991 年发布初始版本。Vim 有着悠久的历史;它起源于 Vi 编辑器&#xff08;1976 年&#xff09;&#xff0c;至今仍在开发中。(Vim has a rich history; it origina…

css+html 爱心❤

效果 代码实现 html <div class"main"><div class"aixin"></div></div>css .main {transform: rotate(-45deg);}.aixin {height: 100px;width: 100px;background-color: red;margin: auto;margin-top: 200px;position: relativ…

MySQL第一次作业(基本操作)

目录 一、登陆数据库 二、创建数据库zoo 三、修改数据库zoo字符集为gbk 四、选择当前数据库为zoo 五、查看创建数据库zoo信息 六、删除数据库zoo 一、登陆数据库 指令&#xff1a; mysql -u root -p 二、创建数据库zoo 指令&#xff1a; create database zoo; 三、修改数…

基于PHP+MySQL组合开发的多用户自定义商城系统源码 附带源代码包以及搭建教程

系统概述 互联网技术的飞速发展&#xff0c;电子商务已成为人们日常生活中不可或缺的一部分。商城系统作为电子商务的核心&#xff0c;其开发技术和用户体验直接影响着电商平台的竞争力和用户满意度。本文旨在介绍一个基于PHPMySQL组合开发的多用户自定义商城系统&#xff0c;…

C++学习~~string类

1.STL简单介绍 &#xff08;1&#xff09;标准模版库&#xff0c;是C里面的标准库的一部分&#xff0c;C标准库里面还有其他的东西&#xff0c;但是我们不经常使用&#xff0c;我们经常使用的还是STL这个标准库部分。 &#xff08;2&#xff09;六大件&#xff1a;仿函数&…

C# WinForm —— 16 MonthCalendar 介绍

1. 简介 可以选择单个日期&#xff0c;也可以选择一段日期&#xff0c;在选择时间范围上 比较适用&#xff0c;但不能跨月份选择日期范围 在直观上&#xff0c;可以快速查看、选择日期/日期范围 2. 常用属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般…

Uni-app基础知识

uni-app组成和跨端原理 | uni-app官网uni-app,uniCloud,serverless,uni-app组成和跨端原理,基本语言和开发规范,编译器,运行时&#xff08;runtime&#xff09;,逻辑层和渲染层分离https://uniapp.dcloud.net.cn/tutorial/1.adb连接模拟器 找到adb所在位置&#xff08;一般在hb…

C++ 程序员常用的VScode的插件

vscode中好用的插件 Better CommentsBookmarksC/C ThemeChinese (Simplified) (简体中文) Language Pack for Visual Studio CodeclangdClang-FormatCodeLLDBCMakeCMake ToolsCode RunnerCode Spell CheckerCodeSnapColor Highlightvscode-mindmapDraw.io IntegrationError Len…

对称加密算法的应用场景

随着信息技术的飞速发展&#xff0c;数据安全成为了至关重要的议题。在保护数据传输和存储的过程中&#xff0c;加密算法扮演着不可或缺的角色。其中&#xff0c;对称加密算法&#xff0c;由于其高效性和易用性&#xff0c;被广泛应用于各种场景中。本文将探讨对称加密算法的主…

Kubernets多master集群构建负载均衡

前言 在构建 Kubernetes 多 Master 集群时&#xff0c;实现负载均衡是至关重要的一环。通过多台 Master 节点配合使用 Nginx 和 Keepalived 等工具&#xff0c;可以有效提高集群的可靠性和稳定性&#xff0c;确保系统能够高效运行并有效应对故障。接下来将介绍如何配置这些组件…

物业水电抄表系统的全面解析

1.系统概述 物业水电抄表系统是现代物业管理中的重要组成部分&#xff0c;它通过自动化的方式&#xff0c;实时监控和记录居民或企业的水电使用情况&#xff0c;极大地提高了工作效率&#xff0c;降低了人工抄表的错误率。该系统通常包括数据采集、数据传输、数据分析和数据展…

链表OJ题(移除链表元素,反转链表,分割链表,环形链表(是否成环问题),链表中间节点(快慢指针讲解),环形链表(找入环节点))“题目来源力扣附带题目链接”

目录 1.移除链表元素 2.反转链表 2.1三指针法 2.2头插法 3.分割链表 4.链表的中间节点&#xff08;快慢指针&#xff09; 4.1快慢指针 4.2求链表的中间节点 5.环形链表 5.1环形链表是否成环 5.2环形链表入环节点 5.3入环节点推论的不完备性说明 1.移除链表元素 移除…

Microsoft Threat Modeling Tool 使用(三)

Boundary&#xff08;边界&#xff09; 本文介绍信任边界&#xff0c;基于 SDL TM Knowledge Base (Core) 模版&#xff0c;这是一个通用的威胁建模模板&#xff0c;非常适合初学者和大多数威胁建模需求。 这些边界&#xff08;Boundary&#xff09;在微软威胁建模工具中用于表…

Java多线程与高并发

1、什么是进程?什么是线程? 进程:进程是程序的基本执行实体;另外一种解释是进程是一个应用程序(1个进程是一个软件)。 线程:线程是操作系统能够进行运算调度的最下单位。它被包含在进程之中,是进程中的实际运作单位;是一个进程中的执行场景/执行单元。 注意:。一个进…

在云服务器上运行StyleGAN3生成伪样本

首先是传入数据&#xff0c;这里我们不做赘述。 对于数据格式的裁剪&#xff0c;可以通过以下代码进行&#xff1a; from glob import glob from PIL import Image import os from tqdm import tqdm from tqdm.std import trangeimg_path glob(r"C:\Users\Administrato…

【Oracle篇】rman物理备份工具的基础理论概述(第一篇,总共八篇)

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&am…