栈(数据结构)——C语言

1 概念与结构

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

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

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

栈的实现⼀般可以使⽤数组或者链表实现,相对⽽⾔数组的结构实现更优⼀些。因为在前链表中尾插需要遍历单链表,时间复杂度比数组尾插的时间复杂度高,数组在尾上插入数据的代价⽐较⼩,并且栈不存在从栈底直接取出,必须满足从栈顶取出,就不存在非空的头插,所以不论是出栈,入栈数组的时间复杂度都为o(1)。

2 栈的实现

和前面的数据结构实现一样,创建三个文件stack.h,stack.c,test.c,分别为头文件,函数实现文件,以及测试文件(检验实现的函数是否正确)。

stack.h

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

这里很之前的一样,栈里存的元素。可以是各种数据类型,为了方便后续改成其他类型,这里重定义数据类型为SDataType,这里以int为例,Stack结构体里,包含数组,栈顶位置top,以及空间大小capacity。

初始化StackInit

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

断言传的指针非空,数组置为空,栈顶为置和空间大小都为0.

入栈StackPush

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

断言传的指针非空,首先要判断空间是否满了,或者空间大小为零,这里就需要申请空间,申请的大小每次为上一次的两倍,如果开始大小为零,则先申请4个大小的空间,然后对top栈顶位置的元素赋值x,最后top位置向后移动++。

判断栈为空StackEmpty

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

这里利用bool类型返回,先断言传的指针非空,这里通过判断top位置是否为0,来判断栈是否为空。

出栈StackPop

void StackPop(ST* ps)
{assert(!StackEmpty(ps));ps->top--;
}

先判断栈是否为空,为空则不能出栈,这里直接将top位置向前移动一位,相当于合法访问的位置比原来的栈少了一个,即将栈顶元素拿出来了。

读取栈顶元素StackTop

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

先判断栈是否为空,为空则没有栈顶元素,这里直接通过数组下标访问,找到栈顶元素。

元素个数STSize

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

断言传的指针非空,直接返回Top位置,即为数组元素个数。

销毁栈StackDestory

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

先销毁数组中元素,不为空,就直接释放掉,置为空,栈顶位置和空间大小都置为0。

3.整体代码

Stack.h

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

Stack.c

#include"Stack.h"
void StackInit(ST*ps)
{assert(ps);ps->arr = NULL;ps->top = ps->capacity = 0;
}void StackDestory(ST* ps)
{if (ps->arr != NULL){free(ps->arr);}ps->arr = NULL;ps->top = ps->capacity = 0;
}void StackPush(ST* ps, SDataType x)
{assert(ps);if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SDataType* tmp = (SDataType*)realloc(ps->arr,newcapacity * sizeof(SDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newcapacity;}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--;
}SDataType StackTop(ST* ps)
{assert(!StackEmpty(ps));return ps->arr[ps->top-1];
}int STSize(ST* ps)
{assert(ps);return ps->top;
}

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

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

相关文章

如何动态改变本地的ip

在当今数字化时代&#xff0c;网络连接已成为我们日常生活和工作中不可或缺的一部分。无论是出于隐私保护、突破地域限制&#xff0c;还是为了测试和优化网络应用&#xff0c;动态改变本地IP地址的需求日益增多。本文将详细介绍如何安全、有效地实现这一目标&#xff0c;旨在帮…

Linux巡检利器xsos的安装和使用

一、 一般项目基本完成的时候&#xff0c;后期运维工作的重点就是及时的&#xff0c;合理的频率巡检了&#xff0c;巡检的目的主要是及时发现各种各样的问题 那么&#xff0c;自己编写shell脚本是大部分人的第一选择&#xff0c;这里有个比较麻烦的地方&#xff0c;shell脚本…

Aatrox-Bert-VITS2部署指南

一、模型介绍 【AI 剑魔 ①】在线语音合成&#xff08;Bert-Vits2&#xff09;&#xff0c;将输入文字转化成暗裔剑魔亚托克斯音色的音频输出。 作者&#xff1a;Xz 乔希 https://space.bilibili.com/5859321 声音归属&#xff1a;Riot Games《英雄联盟》暗裔剑魔亚托克斯 …

分布式IO模拟量模块:多领域应用的高效能解决方案

分布式IO模拟量模块是分布式IO系统中的重要组件&#xff0c;用于实现现场设备或过程的模拟量信号的采集、监视和控制。该模块通常与现场总线耦合器配合使用&#xff0c;能够接收来自现场设备的模拟量信号&#xff08;如电流、电压等&#xff09;&#xff0c;并将其转换为数字信…

YOLOv11在目标检测中的应用及其与PaddleDetection的对比

近年来&#xff0c;目标检测模型在诸如自动驾驶、安全监控等应用中发挥了关键作用。众多模型中&#xff0c;YOLO&#xff08;You Only Look Once&#xff09; 系列凭借其在速度和精度之间的良好平衡脱颖而出。YOLOv11 作为该系列的最新版本之一&#xff0c;凭借其多项创新&…

FPGA秋招必看基础 | FPGA设计流程

关注&#x1f446; 望森FPGA &#x1f446; 查看更多FPGA资讯 这是望森的第 30 期分享 作者 | 望森 来源 | 望森FPGA 目录 摘要 1 明确需求、设计系统架构 2 RTL 输入 3 功能仿真&#xff08;Behavioral Simulation&#xff09; 4 综合&#xff08;Synthesis&#xff09;…

Qgis 开发初级 《符号化》

本章主要简介Qgis 的矢量图层的符号化。Qgis的符号化具体作用于每个图层&#xff0c;图层通过具体的方法设置符号化样式。 1、QgsFeatureRenderer Qgs的符号化类主要是QgsFeatureRenderer&#xff0c;这是一个抽象类&#xff0c;它派生出了许多类&#xff0c;如下所示。常用的…

self-supervised learning(BERT和GPT)

1芝麻街与NLP模型 我們接下來要講的主題呢叫做Self-Supervised Learning&#xff0c;在講self-supervised learning之前呢&#xff0c;就不能不介紹一下芝麻街&#xff0c;為什麼呢因為不知道為什麼self-supervised learning的模型都是以芝麻街的人物命名。 因為Bert是一個非常…

使用Bert+BiLSTM+CRF训练 NER任务

使用的数据集在这里E-Commercial NER Dataset / 电商NER数据集_数据集-阿里云天池 针对面向电商的命名实体识别研究&#xff0c;我们通过爬取搜集了淘宝商品文本的标题&#xff0c;并标注了4大类&#xff0c;9小类的实体类别。具体类型及实体数量如下 针对面向电商的命名实体…

iptables防火墙总结

iptables防火墙总结 四表五链 P 默认策略&#xff0c;-p 协议 出口防火墙&#xff0c;默认配置&#xff0c;使用Forword&#xff0c;采用-P 例题&#xff1a;设置iptables防火墙默认不允许任何数据包进入&#xff0c;相应命令是&#xff1a; Iptables -t filter -P FORWORD -j…

【数据结构】五分钟自测主干知识(十一)

上回&#xff08;半年前&#xff09;我们讲了二叉树&#xff0c;如果我们要找到二叉树某序遍历下的前驱和后继&#xff0c;我们需要对其作动态遍历求得&#xff0c;比较费时&#xff1b;或者给每个结点增加两个指针域prior和next&#xff0c;但比较费空间。 有没有既能省时间&…

【K8S系列】Kubernetes Service 基础知识 详细介绍

在 Kubernetes 中&#xff0c;Service 是一种抽象的资源&#xff0c;用于定义一组 Pod 的访问策略。它为这些 Pod 提供了一个稳定的访问入口&#xff0c;解决了 Pod 可能频繁变化的问题。本文将详细介绍 Kubernetes Service 的类型、功能、使用场景、DNS 和负载均衡等方面。 1.…

Openlayers高级交互(2/20):清除所有图层的有效方法

Openlayers项目中,经常会放置很多的图层,在业务操作的时候,会做出删除所有图层的行为。这里面给出了一个详细的方法,能够有效的解决 清除所有图层的问题。 效果图 专栏名称内容介绍Openlayers基础实战 (72篇)专栏提供73篇文章,为小白群体提供基础知识及示例演示,能解决…

[软件工程]—桥接(Brige)模式与伪码推导

桥接&#xff08;Brige&#xff09;模式与伪码推导 1.基本概念 1.1 动机 由于某些类型的固有的实现逻辑&#xff0c;使它们具有两个变化的维度&#xff0c;乃至多个维度的变化。如何应对这种“多维度的变化”&#xff1f;如何利用面向对象技术是的类型可以轻松的沿着两个乃至…

022_matrix_dancing_in_Matlab中求解一个超简单的矩阵问题

矩阵体操 首先&#xff0c;可以复习一下向量、矩阵和索引的基础知识。 向量约定矩阵约定矩阵索引 一般而言&#xff0c;我们利用进行计算大概就是以下的步骤&#xff1a; #mermaid-svg-UovF0Uldf5XxntJi {font-family:"trebuchet ms",verdana,arial,sans-serif;fo…

MFC实现以不规则PNG图片作为窗口背景

效果图 显示的不规则PNG图片 头文件 #pragma once #include <gdiplus.h> #pragma comment (lib,"Gdiplus.lib")// CShowBack 对话框class CShowBack : public CDialogEx {DECLARE_DYNAMIC(CShowBack) public:CShowBack(CWnd* pParent nullptr); // 标准构…

C++学习路线(二十二)

构造函数 构造函数作用 在创建一个新的对象时&#xff0c;自动调用的函数&#xff0c;用来进行“初始化”工作:对这个对象内部的数据成员进行初始化。 构造函数特点 1.自动调用(在创建新对象时&#xff0c;自动调用) 2.构造函数的函数名&#xff0c;和类名相同 3.构造函数…

react18中的jsx 底层渲染机制相关原理

jsx 底层渲染机制 渲染 jsx 时&#xff0c;会先解析 jsx&#xff0c;生成一个虚拟 dom(virtual dom)。然后将虚拟 dom 渲染成真实 dom。如果 jsx 中包含事件&#xff0c;会将事件绑定到真实 dom 上。 虚拟 dom 对象&#xff0c;是框架内部构建的一套对象体系&#xff0c;对象…

无废话、光速上手 React-Router

React-Router React Router 是一个用于 React 应用的声明式路由库。它允许开发者通过组件化的方式定义应用的路由结构&#xff0c;使得路由管理更加直观和可维护 安装 pnpm i react-router-dom定义路由 定义路由有两种方式&#xff0c;分别是对象路由和路由组件&#xff0c…

AIGC时代 | 从零到一,打造你的专属AI Chat应用!

文章目录 目标功能概要&#xff08;1&#xff09;Chat 交互界面&#xff08;2&#xff09;流式接口&#xff08;3&#xff09;多轮会话&#xff08;4&#xff09;打字效果 系统架构&#xff08;1&#xff09;大模型服务层&#xff08;2&#xff09;应用服务层&#xff08;3&…