栈(用C语言实现)

news2024/9/20 20:18:57

1. 栈

1.1 概念与结构

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

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

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

但栈要怎么实现呢?使用数组还是用链表?

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优⼀些。

因为数组在尾上插入数据的代价比较小。

下面用一幅图来给大家解释一下用链表还是数组。

1.2链表实现栈的优缺点:

优点:

1、任意位置插入删除O(1)

2、按需申请释放空间


缺点:

1、不支持下标随机访问

2、CPU高速缓存命中率会更低

1.2.1链表实现栈的缺点: 

1.额外内存开销:链表实现的栈需要为每个节点分配内存空间来存储数据和指针。相比于数组实现的栈,链表实现需要额外的内存开销来维护节点之间的指针关系,可能导致内存碎片化。

2.动态内存分配:链表实现的栈需要通过动态内存分配来创建和释放节点。这涉及到频繁的内存分配和释放操作,可能导致内存管理的复杂性和性能开销。在某些情况下,可能会出现内存分配失败或内存泄漏的问题。

3.指针操作开销:链表实现的栈需要通过指针进行节点之间的连接操作。这包括插入和删除节点时的指针修改,可能涉及到多个指针的更新。相比于数组实现的栈,链表实现的栈需要更多的指针操作,可能会带来一定的性能开销。

3.随机访问的限制:链表是一种顺序访问的数据结构,无法像数组一样通过索引进行随机访问。如果需要在栈中进行随机访问元素,链表实现的栈可能不太适合,而数组实现的栈更具优势。 

1.3顺序表的优缺点:

优点:

1、尾插尾删效率高。

2、下标的随机访问。

3、CPU高速缓存命中率会更高


缺点:

1、前面部分插入删除数据,效率是O(N),需要挪动数据。

2、空间不够,需要扩容。a、扩容是需要付出代价的b、一般还会伴随空间浪费。 

1.3.1顺序表实现栈的优点:

1.内存连续性:顺序表在内存中是连续存储的,相比于链表的动态内存分配,顺序表的元素在物理上更加紧凑。这样可以减少内存碎片化,提高内存的利用效率。

2.随机访问:顺序表可以通过索引直接访问栈中的元素,具有随机访问的能力。这意味着可以快速访问栈中任意位置的元素,而不需要遍历整个链表。

3.操作简单高效:顺序表的插入和删除操作只涉及元素的移动,不需要额外的指针操作和动态内存分配。这使得操作相对简单高效,并且在某些情况下比链表实现更快。

4.空间效率:相比于链表实现,顺序表不需要额外的指针来维护节点之间的连接关系,因此可以节省一定的空间开销。只需要存储元素本身和栈顶指针即可。 

综上所述:选择顺序表较好一点。

栈的实现:

头文件:Stack.h

typedef int STDataType;

typedef struct Stack {

STDataType* a;

int top;

int capacity;

}ST;//定义栈的结构

// 初始化栈

void STInit(ST* ps);

// 销毁栈 void STDestroy(ST* ps);

// ⼊栈

void STPush(ST* ps, STDataType x);

//出栈

void STPop(ST* ps);

//取栈顶元素 STDataType STTop(ST* ps);

//获取栈中有效元素个数

int STSize(ST* ps);

//栈是否为空

bool STEmpty(ST* ps);

实现栈的文件:Stack.c

#include"Stack.h"
void STInit(ST* ps)
{
    assert(ps);
    ps->arr = NULL;
    ps->capacity = ps->top = 0;
}

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

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

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

void STackPop(ST* ps)
{

    assert(ps);
    assert(!StackEmpty(ps));
    --ps->top;

}

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

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

 

测试文件:text.c

#include"Stack.h"
void STText()
{
    //ST st;
    //STInit(&st);
    //STackPush(&st, 1);
    //STackPush(&st, 2);
    //STackPush(&st, 3);
    //STackPush(&st, 4);
    //STackPush(&st, 5);
    //printf("size==%d\n", STSize(&st));
    STackPop(&st);
    //while (!StackEmpty(&st))
    //{
    //    STDateType date = STacktop(&st);
    //    printf("%d ", date);
    //    STackPop(&st);
    //}
    //printf("\n");
    //printf("size==%d\n", STSize(&st));
    //STDestroy(&st);
    

}
int main()
{
    STText();

    return 0;
}

有兴趣的小伙伴可以测试一下,代码是完全没有错误的。 

 

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

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

相关文章

多源字段聚合重塑算法

要求如下 [[{"oone": "评估是否聘请第三方机构","otwo": null,"othree": "test",},{"oone": "评估是否聘请第三方机构","otwo": null,"othree": "test",}],[{"oon…

使用 Flask 3 搭建问答平台(三):注册页面模板渲染

前言 前端文件下载 链接https://pan.baidu.com/s/1Ju5hhhhy5pcUMM7VS3S5YA?pwd6666%C2%A0 知识点 1. 在路由中渲染前端页面 2. 使用 JinJa 2 模板实现前端代码复用 一、auth.py from flask import render_templatebp.route(/register, methods[GET]) def register():re…

Elasticsearch:评估搜索相关性 - 第 1 部分

作者:来自 Elastic Thanos Papaoikonomou, Thomas Veasey 这是一系列博客文章中的第一篇,讨论如何在更好地理解 BEIR 基准的背景下考虑评估你自己的搜索系统。我们将介绍具体的技巧和技术,以便在更好地理解 BEIR 的背景下改进你的搜索评估流程…

java用freemarker导出word

freemarker导出word 第一步、将word转换为xml格式第二步、将转换后的xml文件修改后缀为ftl后复制到项目 resources 目录下(可以自己新建一个文件夹放在文件夹中)第三步、格式化xml代码(如果问价太大可能会无法格式化)这时候需要在…

鸿蒙语言基础类库:【@system.router (页面路由)】

页面路由 说明: 从API Version 8 开始,该接口不再维护,推荐使用新接口[ohos.router])。本模块首批接口从API version 3开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 导入模块 import router from system.ro…

Unity扩展SVN命令

可以直接在unity里右键文件提交和查看提交记录 顶部菜单栏上回退和更新整个unity工程 SvnForUnity.CS 记得要放在Editor文件夹下 using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using UnityEditor; using Unity…

前端pc和小程序接入快递100(跳转方式和api方式)====实时查询接口

文章目录 跳转方式微信小程序(我以uniapp为例)pc api接入说明关于签名计算成功示例 跳转方式 没有任何开发成本,直接一键接入 可以直接看官方文档 https://www.kuaidi100.com/openapi/api_wxmp.shtml 微信小程序(我以uniapp为例…

算法日记day 11(KMP算法)

一、KMP算法 基本原理: KMP算法(Knuth-Morris-Pratt算法)是一种用于在一个文本串(字符串)中查找一个模式串(子串)的高效算法。它的主要优点是在匹配过程中避免了回溯(backtracking…

【QT】label中添加QImage图片并旋转(水平翻转、垂直翻转、顺时针旋转、逆时针旋转)

目录 0.简介 1.详细代码及解释 1)原label显示在界面上 2)水平翻转 3)垂直翻转 4)顺时针旋转45度 5)逆时针旋转 0.简介 环境:windows11 QtCreator 背景:demo,父类为QWidget&a…

盒须图boxplot 展示第6条线

正常情况下,盒须图是有5条线的,但是实际产品场景是需要6条线,看了下echarts官网,没看到可配置的地方,只能自己骚操作了,效果图如下: 重点:用两条x轴,第6条线挂在第二条x…

【flink】之如何快速搭建一个flink项目

1.通过命令快速生成一个flink项目 curl https://flink.apache.org/q/quickstart.sh | bash -s 1.19.1 生成文件目录: 其中pom文件包好我们所需要的基础flink相关依赖 2.测试 public class DataStreamJob {public static void main(String[] args) throws Except…

GitHub 令牌泄漏, Python 核心资源库面临潜在攻击

TheHackerNews网站消息,软件供应链安全公司 JFrog 的网络安全研究人员称,他们发现了一个意外泄露的 GitHub 令牌,可授予 Python 语言 GitHub 存储库、Python 软件包索引(PyPI)和 Python 软件基金会(PSF&…

《昇思25天学习打卡营第25天|onereal》

初学入门/初学教程/08-模型训练.ipynb 模型训练 模型训练一般分为四个步骤: 构建数据集。定义神经网络模型。定义超参、损失函数及优化器。输入数据集进行训练与评估。 现在我们有了数据集和模型后,可以进行模型的训练与评估。 构建数据集 首先从数…

国内AI算力芯片厂商群雄逐鹿,创新产品引领边缘计算新风尚

近年来,随着人工智能技术的飞速发展,AI算力芯片作为支撑这一技术的关键基础设施,受到了前所未有的关注。国内厂商纷纷加入竞争,四川万物纵横科技就是其中争流涌进的一员,公司不仅在技术上追求创新,还在市场…

FastAPI 学习之路(五十二)WebSockets(八)接受/发送json格式消息

前面我们发送的大多数都是text类型的消息,对于text消息来说,后端处理出来要麻烦的多,那么我们可以不可以传递json格式的数据,对于前后端来说都比较友好,答案是肯定的,我们需要做下处理。 首先,…

LNMP环境配置问题整理

首先是一键安装直接报错: 换教程:搭建LNMP,步骤最详细,附源码,学不会打我-CSDN博客 mysql安装成功之后: MySQL 启动报错:Job for mysqld.service failed because the control process exited …

Java 在PDF中替换文字(详解)

目录 使用工具 Java在PDF中替换特定文字的所有实例 Java在PDF中替换特定文字的第一个实例 Java在PDF中使用正则表达式替换特定文字 其他替换条件设置 可能出现的问题及解决方案 PDF文档中的信息随时间的推移可能会发生变化,比如产品价格、联系方式等。为了确保…

迭代学习笔记

一、迭代学习定义和分类 1、直观理解 迭代学习一般应用于重复性的场景。比如控制一个单自由度的小车以特定的速度曲线移动到指定位置,整个时间是10s,控制频率是0.01,那么整个控制序列就会有1000个点。这1000个点在10s内依次发出&#xff0c…

网络编程-TCP 协议的三次握手和四次挥手做了什么

TCP 协议概述 1. TCP 协议简介 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。 TCP 协议提供可靠的通信服务,通过校验和、序列号、确认应答、重传等机制保证数据传输…

Pytorch学习笔记day4——训练mnist数据集和初步研读

该来的还是来了hhhhhhhhhh,基本上机器学习的初学者都躲不开这个例子。开源,数据质量高,数据尺寸整齐,问题简单,实在太适合初学者食用了。 今天把代码跑通,趁着周末好好的琢磨一下里面的各种细节。 代码实…