C数据结构:栈

简介

   在之前的几篇文章中已经详细讲解了线性表中的 顺序表、单链表。每一种不同的数据结构都有它独特的结构和应用之处,今天将再次给大家介绍一个新的线性表:

1. 栈:一种特殊的线性表,其中只允许在固定的一端进行插入和删除元素的操作。

2. 栈的原型:其中进行数据插入的和删除操作的一端称为栈顶,另一端称为栈底。

3. 栈的原则:栈中的数据元素遵守 后进先出(LIFO)的原则   

4. 栈的场景:在日常生活中,(电梯)就相当于一个栈,先进去的人后出,后进去的人总是先出   

🔑栈的两个经典操作:
压栈:栈的插入操作叫做 进栈 / 压栈  / 入栈  (入数据在栈顶)

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

顺序存储栈

顺序存储栈是栈的顺序实现。顺序栈是指利用顺序存储结构(数组)实现的栈。采用地址连续的存储空间依次存储栈中数据元素。

main.c

#include <stdlib.h>
#include <stdio.h>
#include "sqstack.h"

int main()
{
    sqstack*st;
    st = st_create();
    if(st == NULL)
        exit(1);
    datatype arr[] = {11,22,33,44,55,66,77,88};
    for(int i=0;i<8;i++)
    {
        st_push(st,&arr[i]);
    }
    datatype temp;
    st_travel(st);
    while(st_pop(st,&temp)==0)
    {
        printf("POP %d \n",temp);
    }
    
    st_destroy(st);
    return 0;
}

sqstack.h

#ifndef SQSTACK_H
#define SQSTACK_H
#define MAXSIZE 5
typedef int datatype;

typedef struct node_st
{
    datatype data[MAXSIZE];
    int top;
}sqstack;


sqstack* st_create(void);

int st_isempty(sqstack*);

int st_push(sqstack*,datatype*);

int st_pop(sqstack*,datatype*);

int st_top(sqstack*,datatype*);

void st_travel(sqstack*);

int st_destroy(sqstack*);

#endif

sqstack.c

#include <stdlib.h>
#include <stdio.h>
#include "sqstack.h"

sqstack* st_create(void)
{
    sqstack*st;
    st = malloc(sizeof(*st));
    if(st == NULL)
        return NULL;
        
    st->top = -1;
    return st;
}
int st_isempty(sqstack*st)
{
    if(st->top == -1)
        return 0;
    return 1;
}
int st_push(sqstack*st,datatype* data)
{
    if(st->top == MAXSIZE-1 )
        return -1;
    st->data[++st->top] = *data;
    return 0;
}
int st_pop(sqstack*st,datatype*data)
{
    if(st_isempty(st) == 0)
        return -1;
    *data = st->data[st->top--];
    return 0;
}
int st_top(sqstack*st,datatype*data)
{
    if(st_isempty(st )== 0)
        return -1;
    *data = st->data[st->top];

}
void st_travel(sqstack*st)
{
    if(st_isempty(st)== 0)
        return;
    for(int i=0;i<=st->top;i++)
    {
        printf("%d ",st->data[i]);
    }
    printf("\n");
}

int st_destroy(sqstack*st)
{
    free(st);
    st = NULL;
    return 0;
}

链式存储栈

本文的链式存储为对上一篇文章(链表高级篇)中的双向链表(lib2)的内容进行封装生成的二次使用,如大家感兴趣可以去上篇文章找下源码,也可以给我留言,我给大家私发代码。

main.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stack.h"

struct score_st
{
    int id;
    char name[32];
    int math;
    int chinese;
};

void print_s(const void *record)
{
    const struct score_st*r = record;
    printf("%d %s %d %d \n",r->id,r->name,r->math ,r->chinese);

}

int main()
{
    int ret; 
    STACK* st = stack_create(sizeof(struct score_st));
    struct score_st temp;
    if(st == NULL)
        return -1;
    for(int i=0;i<5;i++)
    {
        temp.id = i;
        snprintf(temp.name,sizeof(temp.name),"std_%d",i);
        temp.math = rand()%100;
        temp.chinese = rand()%100;
        stack_push(st,&temp);
    }
    while(1)
    {
        ret = stack_pop(st,&temp);
        if(ret == -1)
            break;
        print_s(&temp);
    }

    stack_destroy(st);
    return 0;
}

stack.c

#include <stdlib.h>
#include <stdio.h>
#include "stack.h"


STACK* stack_create(int initsize)
{
    return llist_create(initsize);

}

int stack_push(STACK*ptr,const void *data)
{
    return llist_insert(ptr,data,LLIST_FORWARD);
}

static int always_match(const void*p1,const void*p2)
{
    return 0;
}
int stack_pop(STACK*ptr ,void* data)
{
    return llist_fetch(ptr,(void*)0,always_match,data);
}
void stack_destroy(STACK* ptr)
{

    return llist_destroy(ptr);
}

stack.h

#ifndef STACK_H
#define STACK_H

#include "llist.h"


typedef LLIST STACK;

STACK* stack_create(int);

int stack_push(STACK*,const void *data);

int stack_pop(STACK* ,void* daata);

void stack_destroy(STACK*);


#endif

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Rust Postgres实例

Rust Postgres介绍 Rust Postgres是一个纯Rust实现的PostgreSQL客户端库&#xff0c;无需依赖任何外部二进制文件2。这意味着它可以轻松集成到你的Rust项目中&#xff0c;提供对PostgreSQL的支持。 特点 高性能&#xff1a;Rust Postgres提供了高性能的数据库交互功能&#…

DI-engine强化学习入门(九)环境包裹器(Env Wrapper)

在强化学习中&#xff0c;环境&#xff08;Environment&#xff09;是智能体&#xff08;Agent&#xff09;进行学习和互动的场所&#xff0c;它定义了状态空间、动作空间以及奖励机制。Env Wrapper&#xff08;环境包装器&#xff09;提供了一种方便的机制来增强或修改原始环境…

揭秘新时代的内容创作:一键生成的AI黑科技

在数字媒体的浪潮下&#xff0c;内容创作已成为连接人与信息的重要桥梁。然而&#xff0c;头条、公众号等平台上的爆文创作&#xff0c;对很多内容创作者来说却是一项挑战。“从选题到找素材&#xff0c;再到成文&#xff0c;”这个过程不仅耗时至少1到2个小时&#xff0c;而且…

【go项目01_学习记录08】

学习记录 1 模板文件1.1 articlesStoreHandler() 使用模板文件1.2 统一模板 1 模板文件 重构 articlesCreateHandler() 和 articlesStoreHandler() 函数&#xff0c;将 HTML 抽离并放置于独立的模板文件中。 1.1 articlesStoreHandler() 使用模板文件 . . . func articlesSt…

产品评测:SmartX 与 Nutanix 超融合在数据库场景下的性能表现

重点内容 SmartX 与 Nutanix 超融合分布式存储设计差异如何影响数据库性能表现。重点测试结论&#xff1a;数据库场景下&#xff0c;SmartX 超融合基于单卷部署的性能&#xff0c;依旧优于 Nutanix 超融合基于多卷部署最佳配置的性能。更多 SmartX、VMware、Nutanix 超融合技术…

高防护皮带机巡检机器人:适应恶劣环境的智能助手

在众多工业领域中&#xff0c;皮带机作为一种重要的物料输送设备&#xff0c;广泛应用于发电厂、煤栈等场所。然而&#xff0c;长期以来&#xff0c;皮带机的巡检工作一直依赖人工&#xff0c;存在着劳动强度大、检测效率低、安全性差等问题。为了解决这些痛点&#xff0c;皮带…

Day05-JavaWeb开发-请求响应(postman工具/参数/案例)分层解耦(三层架构/IOC-DI引入)

1. 请求响应 1.1 概述 1.2 请求-postman工具 1.3 请求-简单参数&实体参数 1.3.1 简单参数 1.3.2 实体参数 1.4 请求-数组集合参数 1.5 请求-日期参数&json参数 1.6 请求-路径参数 1.7 响应-ResponseBody 1.8 响应-案例 2. 分层解耦 2.1 三层架构 2.2 分层解耦(IOC-D…

GitHub Actions 手动触发方式

目录 前言 Star Webhook 手动触发按钮 前言 GitHub Actions 是 Microsoft 收购 GitHub 后推荐的一款 CI/​CD 工具早期可能是处于初级开发阶段&#xff0c;它的功能非常原生&#xff0c;甚至没有直接提供一个手动触发按钮一般的触发方式为代码变动&#xff08;push 、pull…

使用Processing和PixelFlow库创建交互式流体太极动画

使用Processing和PixelFlow库创建交互式流体太极动画 引言准备工作效果展示代码结构代码解析第一部分&#xff1a;导入库和设置基本参数第二部分&#xff1a;流体类定义MyFluidDataConfig 类详解MyFluidData 类详解my_update 方法详解流体类定义完整代码 第三部分&#xff1a;太…

无监督式学习

1.是什么&#xff1f; 无监督式学习与监督式学习**最大的区别就是&#xff1a;**没有事先给定的训练实例&#xff0c;它是自动对输入的示例进行分类或者分群&#xff1b; 优点&#xff1a;不需要标签数据&#xff0c;极大程度上扩大了我们的数据样本&#xff0c;其次不受监督信…

部署 Sentinel 控制台:实现流量管理和监控

序言 Sentinel 是阿里巴巴开源的一款流量防护与监控平台&#xff0c;它可以帮助开发者有效地管理微服务的流量&#xff0c;实现流量控制、熔断降级、系统负载保护等功能。本文将介绍如何在项目中部署和配置 Sentinel 控制台&#xff0c;实现微服务的流量防护和监控。 一、Sen…

WEB基础--单元测试与三层架构

单元测试 为什么要进行单元测试 减少创建类&#xff0c;我们希望在一个类中&#xff0c;并且测试时不需要改代码&#xff0c;那么我们就要用到junit单元测试 常见测试分类 黑盒测试 黑盒测试也叫功能测试&#xff0c;主要关注软件每个功能是否实现&#xff0c;并不关注软件代…

【websocket-客户端可视化工具】

postman 新版postman (版本v11以上) &#xff0c;除了http协议&#xff0c;还支持了Websocket&#xff0c;MQTT&#xff0c;gRPC等多种连接协议&#xff0c;可以作为多种协议的客户端&#xff0c;使用起来非常方便。 使用 服务端代码 这里以websocket协议举例&#xff0c;代…

【Linux】网络接口绑定和组合的操作实例

网络接口绑定和组合的操作实例 &#xff08;一&#xff09;网卡1. 增2. 查3. 激活——设置网络接口 &#xff08;二&#xff09;网络接口绑定1. 概述2. 实验操作3. 删除绑定 &#xff08;三&#xff09;网络接口组合1. 概述2. 实验操作 &#xff08;一&#xff09;网卡 1. 增 …

分割模型Maskformer系列

maskformer&#xff1a;Per-Pixel Classification is Not All You Need for Semantic Segmentation 论文地址&#xff1a;https://arxiv.org/pdf/2107.06278 1.概述 传统的语义分割方法通常采用逐像素分类&#xff08;per-pixel classification&#xff09;&#xff0c;而实…

【JAVA基础之装箱和拆箱】自动装箱和自动拆箱

&#x1f525;作者主页&#xff1a;小林同学的学习笔录 &#x1f525;mysql专栏&#xff1a;小林同学的专栏 目录 1.包装类 1.1 概述 1.2 Integer类 1.3 装箱和拆箱 1.4 自动装箱和自动拆箱 1.5 基本类型与字符串之间的转换 1.5.1 基本类型转换为字符串 1.5.2 字符串转…

带你破解晶振PCB的布局要点!

一、晶振的分类 01 无源晶振 无源晶振器是一种 passives 振荡器&#xff0c;它不需要外部电源来维持振荡。它的振荡频率由晶体的物理尺寸和材料特性决定&#xff08;一般都采无源晶振&#xff09;。 02 有源晶振 有源晶振器是一种 active 振荡器&#xff0c;它需要外部电源来…

计算机中GPU快不行的几个标志,看下有没有你遇到的

GPU是处理图形密集型任务的主要组件。尽管它非常耐用,但它最终会磨损并开始失效。在到达生命的终结之前,它通常会显示出即将发生故障的迹象,需要及时修复或更换。本指南详细介绍了这些标志。 在我们开始之前 在深入研究GPU故障的迹象之前,重要的是要承认,下面提到的一些…

卷积通用模型的剪枝、蒸馏---蒸馏篇--RKD关系蒸馏(以deeplabv3+为例)

本文使用RKD实现对deeplabv3+模型的蒸馏;与上一篇KD蒸馏的方法有所不同,RKD是对展平层的特征做蒸馏,蒸馏的loss分为二阶的距离损失Distance-wise Loss和三阶的角度损失Angle-wise Loss。 一、RKD简介 RKD算法的核心是以教师模型的多个输出为结构单元,取代传统蒸馏学习中以教…

Leetcode—394. 字符串解码【中等】

2024每日刷题&#xff08;131&#xff09; Leetcode—394. 字符串解码 实现代码 class Solution { public:string decodeString(string s) {string curstr;int curNum 0;stack<pair<string, int>> st; for(char c: s) {if(isdigit(c)) {curNum curNum * 10 (c…
最新文章