数据结构-栈(C语言简单实现)

news2024/11/24 16:49:56

简介

  • 栈是一种数据结构
  • 栈可以用来存放数字
  • 一次只能向栈里加入一个数字,一次也只能从栈里获得一个数字
  • 栈里到的数字有前后顺序,先进入到的数字在前,后进入的数字在后
  • 每次从栈里获取的数字一定是最后面的数字,最后获取的数字一定是最前面的数字
  • 这种取数字的方法叫先进后出,后进先出

下面是它存储数据的过程

在这里插入图片描述

下面是它取出这三个数据的过程

上面两幅图展示了栈存储数据和取出数据的一个过程,体现了先进后出,后进先出这个特性。

代码实现

以下就是创建栈的数据结构,并且实现其功能的相关函数。

  1. 定义栈
typedef struct stack{
    int *arr;  // 分配存储区的首地址
    int cap;  // 栈中的元素个数
    int top;  // 入栈和出栈的位置
}stack_t;
  1. 初始化栈
void stack_init(stack_t* pstack, int cap){
    pstack->arr = malloc(sizeof(int) * cap);  // 分配内存给存储区
    if(pstack->arr == NULL){
        printf("栈的存储区分配失败!\n");
        return;
    }
    pstack->cap = cap;  // 初始化传入的元素个数
    pstack->top = 0;  // 一开始入栈的索引是在0
}
  1. 释放栈
void stack_deinit(stack_t* pstack){
    // 释放内存,并重置为0和NULL
    free(pstack->arr);
    pstack->arr = NULL;
    pstack->cap = 0;
    pstack->top = 0;
}
  1. 压栈
void stack_push(stack_t* pstack, int data){
    // 将传入的数据放到栈中
    pstack->arr[pstack->top++] = data;  // 先将数据放入索引为top的位置,然后将top++,往后移
}
  1. 出栈
int stack_pop(stack_t* pstack){
    // 当栈中有数据时,此时top肯定是指向最后一个传进去的数据后一个,此时只需将top--,之后再将数据取出即可
    return pstack->arr[--pstack->top];
}
  1. 判断栈是否已满
int stack_full(stack_t* pstack){
    // 因为top索引是从0开始的,有一个数据进来,top就加1,所以top的值就是当前栈中元素的个数,当它等于cap时,说明栈满了
    return pstack->top >= pstack->cap;  // 满了返回真(非0),没满返回假(0)
}
  1. 判断栈是否为空
int stack_empty(stack_t* pstack){
    // 参考第6条,top的值就是当前栈中元素的个数,top值为0说明为空
    return pstack->top == 0;  // 为空返回真(非0),不为空返回假(0)
}
  1. 获取栈中的元素个数
int stack_size(stack_t* pstack){
    // 参考第6条,top的值就是当前栈中元素的个数
    return pstack->top;
}

实例代码

创建三个文件: stack.cstack.hmain.c

  • stack.c定义栈具体的函数
#include "stack.h"

// 初始化栈
void stack_init(stack_t* pstack, int cap){
    pstack->arr = malloc(sizeof(int) * cap);
    if(pstack->arr == NULL){
        printf("栈的存储区分配失败!\n");
        return;
    }
    pstack->cap = cap;
    pstack->top = 0;
}

// 释放栈
void stack_deinit(stack_t* pstack){
    free(pstack->arr);
    pstack->arr = NULL;
    pstack->cap = 0;
    pstack->top = 0;
}

// 压栈
void stack_pull(stack_t* pstack, int data){
    pstack->arr[pstack->top++] = data;
}

// 出栈
int stack_pop(stack_t* pstack){
    return pstack->arr[--pstack->top];
}

// 判断栈是否已满
int stack_full(stack_t* pstack){
    return pstack->top >= pstack->cap;
}

// 判断栈是否为空
int stack_empty(stack_t* pstack){
    return pstack->top == 0;
}

// 获取栈中的元素个数
int stack_size(stack_t* pstack){
    return pstack->top;
}
  • stack.h声明栈的相关函数和定义栈
#ifndef __STACK_H  // 头卫士
#define __STACK_H
#include <stdio.h>
#include <stdlib.h>

// 定义栈的数据结构
typedef struct stack{
    int* arr;
    int cap;
    int top;
}stack_t;

// 声明栈的函数
extern void stack_init(stack_t* pstack, int cap);
extern void stack_deinit(stack_t* pstack);
extern void stack_pull(stack_t* pstack, int data);
extern int stack_pop(stack_t* pstack);
extern int stack_full(stack_t* pstack);
extern int stack_empty(stack_t* pstack);
extern int stack_size(stack_t* pstack);
#endif
  • main.c主函数使用栈
#include "stack.h"

int main(void){
    // 1. 声明一个栈: stack
    stack_t stack;

    // 2. 初始化stack
    stack_init(&stack, 5);

    // 3. 将栈放满数据
    int data = 100;
    printf("开始放入数据: ");
    while(!stack_full(&stack)){
        // 没满的状态下,放入数据
        printf("%d ", data);
        stack_pull(&stack, data++);
    }
    printf("结束!\n");
    printf("此时栈中元素个数为: %d\n\n", stack_size(&stack));

    // 4. 将栈中的数据一个个取出来
    printf("开始取出数据: ");
    while(!stack_empty(&stack)){
        // 非空的状态,取数据
        data = stack_pop(&stack);
        printf("%d ", data);
    }
    printf("结束!\n");
    printf("此时栈中元素个数为: %d\n\n", stack_size(&stack));

    // 5. 释放栈
    stack_deinit(&stack);
    return 0;
}

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

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

相关文章

使用svg生成图像

使用svg生成图像 每个HTML开发人员都应该对可伸缩的向量图形有一个基本的理解。本文会通过使用svg创建一个雨伞图像来介绍一下svg的基本知识。 svg介绍 SVG 意为可缩放矢量图形&#xff08;Scalable Vector Graphics&#xff09;。是一种可以在HTML中创建图像的方式。 我们…

Java # Spring(2)

一、Spring事物 一、分类 编程式事物&#xff1a;代码中硬编码&#xff08;不推荐使用&#xff09; 声明式事物&#xff1a;配置文件中配置&#xff08;推荐使用&#xff09; 分类&#xff1a; 基于xml的声明式事物基于注解的声明式事物 二、隔离级别 ISOLATION_DEFAULT&…

navicat连接postgresql报错

navicat连接postgresql报错 navicat连接postgresql报错 现象 有小伙伴告诉我 安装了新的postgresql 使用navicat连接&#xff0c;报错 ERROR: column "datlastsysoid" does not existLINE 1: SELECT DISTINCT datlastsysoid FROM pg database column “datlastsy…

电源控制--条件稳定

控制系统的条件稳定是指系统在一定条件下能够保持稳定性的特性。稳定性是控制系统设计中非常重要的概念&#xff0c;它涉及系统的输出在时间上是否趋向于有限值或者周期性变化&#xff0c;而不是无限增长或发散。 在控制系统中&#xff0c;条件稳定的要求通常涉及到以下几个方…

可靠传输-选择重传协议SR

一个数据分组的误码就会导致其后续多个数据分组不能被接收方按序接收而丢弃 (尽管它们无乱序和误码)。这必然会造成发送方对这些数据分组的超时重传&#xff0c;显然这是对通信资源的极大费。 为了进一步提高性能&#xff0c;可设法只重传出现误码的数据分组。因此&#xff0c;…

陈述式资源管理方法

陈述式资源管理方法&#xff1a; 1.kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口 2.kubectl 是官方的CLI命令行工具&#xff0c;用于与 apiserver 进行通信&#xff0c;将用户在命令行输入的命令&#xff0c;组织并转化为 apiserver 能识别的…

安卓如何卸载应用

卸载系统应用 首先需要打开手机的开发者选项&#xff0c;启动usb调试。 第二步需要在电脑上安装adb命令&#xff0c;喜欢的话还可以将它加入系统path。如果不知道怎么安装&#xff0c;可以从这里下载免安装版本。 第三步将手机与电脑用数据线连接&#xff0c;注意是数据线&a…

AcWing算法提高课-1.3.17背包问题求具体方案

宣传一下算法提高课整理 <— CSDN个人主页&#xff1a;更好的阅读体验 <— 本题链接&#xff08;AcWing&#xff09; 点这里 题目描述 有 N N N 件物品和一个容量是 V V V 的背包。每件物品只能使用一次。 第 i i i 件物品的体积是 v i v_i vi​&#xff0c;价值…

Linux配置QT Creator环境:ubuntu中安装QT Creator环境

一、前景 目前市面上很多公司使用QT Creator进行界面开发&#xff0c;基本都会选择在Linux环境进行&#xff0c;优点不仅是市场所需&#xff0c;更是方便后期代码的移植&#xff0c;相较于Windows系统&#xff0c;Linux系统移植性非常好。故此篇文章&#xff0c;介绍如何在Linu…

Android 视频播放器dkplayer

列表播放如图所示&#xff1a; 一、依赖 //添加RecyclerView的依赖包implementation androidx.recyclerview:recyclerview:1.2.1// 异步加载图片依赖implementation com.squareup.picasso:picasso:2.5.2// 上拉刷新、下来加载依赖implementation com.scwang.smartrefresh:Smart…

Linux命令200例:mkdir用于创建目录(常用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

centos linux 安装RDMA Soft-RoCE|虚拟机安装Soft-RoCE

什么是Soft-RoCE softRoCE的目标是在所有支持以太网的设备上都可以部署RDMA传输&#xff0c;可以使不具备RoCE能力的硬件和支持RoCE的硬件间进行基于IB语义的交流。 大白话就是模拟RDMA的软件栈&#xff0c;使得在没有RDMA网卡的环境上&#xff0c;也可以运行基于RDMA写的传输…

jenkins流水线

1.拉取代码 https://gitee.com/Wjc_project/yygh-parent.git2、项目编译 mvn clean package -Dmaven.test.skiptrue ls hospital-manage/target3、构建镜像 ls hospital-manage/target docker build -t hospital-manage:latest -f hospital-manage/Dockerfile ./hospital-ma…

ASL国产CS5213 转VGA信号输出音频 替代AG6200安格芯片 HDMI to VGA(带音频)方案设计原理图

CS5213功能&#xff1a;HDMI转VGA带音频输出&#xff0c;专注于设计HDMI转VGA带音频输出。可替代AG6200 AG6201。 CS5213芯片是一个HDMI&#xff08;高清多媒体接口&#xff09;到VGA桥接芯片。 它将HDMI信号转换为标准VGA信号它可以在适配器、智能电缆等设备中设计。 Capst…

用C语言实现定积分计算(包括无穷积分/可自定义精度)

关于严谨性的声明&#xff1a; 在用C语言进行定积分的计算之前&#xff0c;我需要声明以下几点&#xff1a; 一、我们所进行定积分计算的函数都是应当是黎曼可积的&#xff0c;这保证了我们即使均匀地分割区间也保证了积分的收敛性。 二、我们同时还应该认识到&#xff0c;鉴…

一文详解 DolphinDB SQL 标准化

为了提升用户体验&#xff0c;降低用户学习成本和脚本迁移复杂度&#xff0c;自 1.30.17 / 2.00.5 版本开始&#xff0c;DolphinDB 逐步支持了标准化 SQL 的书写方法&#xff1b;并于 1.30.22 / 2.00.10 版本起&#xff0c;对标准 SQL 的常用语法和关键字实现了兼容。 1. 与标…

06-5_Qt 5.9 C++开发指南_Splash 与登录窗口(MouseEvent鼠标事件;注册表;加密)

文章目录 1. 实例功能概述2. 对话框界面设计和类定义3. QDIgLogin 类功能实现3.1 构造函数里的初始化3.2 应用程序设置的存储3.3 字符串加密3.4 用户名和密码输入判断3.5 窗口拖动功能的实现 4. Splash 登录窗口的使用5. 框架及源码5.1 可视化UI设计5.2 qdlglogin.h5.3 qdlglog…

使用vue模拟通讯录列表,对中文名拼音首字母提取并排序

一个功能需求,做一个类似联系人列表的功能,点击名称获取对应的id,样式简陋,只是一个模板,原来是uniapp项目,根据需要改成了vue,需要的自行设计css&#xff08;万是有一个mo的音&#xff09; 流程 获取数据提取首个字的拼音的首个字母排序并分组 上代码&#xff1a; <temp…

zadig安装驱动潜在风险与解决策略

zadig安装驱动潜在风险与解决策略 ✨没事不要闲着乱打驱动&#xff0c;能正常使用的情况下&#xff0c;不要轻易或随意去乱打驱动&#xff0c;可能会导致新的驱动对已有的设备不兼容的问题。✨&#x1f530;特别说明&#xff1a;本文介绍的方法&#xff0c;并不能包治百病&…

Android学习之路(2) 文本设置

Android学习之路(1) 文本 一、设置文本内容 设置文本内容的两种方式&#xff1a; 一种是在XML文件中通过属性android:text设置文本代码如下 <TextViewandroid:id"id/tv_hello"android:layout_width"wrap_content"android:layout_height"wrap_c…