【数据结构】(C语言):栈
栈:
- 线性的集合。
- 后进先出(LIFO,last in first out)。
- 两个指针:指向栈顶和栈底。栈顶指向最后进入且第一个出去的元素。栈底指向第一个进入且最后一个出去的元素。
- 两个操作:入栈(往栈尾添加元素),出栈(从栈尾取出元素)。
- 可以使用链表实现,也可以使用数组实现。本文使用双链表举例。
入栈:往栈顶(栈尾部)添加元素。
(头指针:指向第一个元素。尾指针:指向最后的元素。)

出栈:从栈顶(栈尾部)删除元素。
(头指针:指向第一个元素。尾指针:指向最后的元素。)

C语言实现(双链表):
创建节点(结构体数据类型),并创建具体节点实例的函数:
// 节点(结构体数据类型)
typedef struct Node
{int value; // 存储数据为整数struct Node *next; // 指向下一个数据的指针struct Node *prev; // 指向上一个数据的指针
} LinkNode; // 别名LinkNode
// 创建具体节点实例的函数
LinkNode * createNode(int data)
{LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode)); // 分配内存空间if(node == NULL){perror("Memory allocation failed");exit(-1);}node->value = data;node->prev = NULL;node->next = NULL;return node;
}
本文将头指针、尾指针和栈长度作为全局变量:
LinkNode *header = NULL; // 头指针,指向第一个节点,初始化为NULL
LinkNode *tail = NULL; // 尾指针,指向最后节点,初始化为NULL
int length = 0; // 统计栈有多少元素,初始化为0
入栈:
// 入栈(往栈顶即尾部添加数据)
void push(int data)
{LinkNode *node = createNode(data);if(length == 0) // 空栈,头指针和尾指针都指向新节点{header = node;tail = node;length++;return ;}tail->next = node; // 原最后节点的下一个为新节点node->prev = tail; // 新节点的上一个为原最后节点tail = node; // 尾指针指向新节点,即新节点为最后节点 length++; // 每添加一个元素,length+1
}
获取栈顶元素:
int gettop(void)
{// 栈不为空,则栈顶元素为尾指针指向的最后节点的值if(length != 0) return tail->value;
}
出栈:
int pop(void)
{if(length != 0){// 获取最后节点的值int top = tail->value;// 通过最后节点的prev找到倒数第二个节点,其next指向NULL,则原倒数第二个节点为新的最后节点tail->prev->next = NULL;// 每删除一个节点,length-1length--;// 返回原最后节点的值return top;}
}
遍历栈:
void travel(void)
{if(length == 0) return ;LinkNode *cur = header; // 从链表头部开始遍历,直到最后printf("stack elements:");while(cur != NULL){printf("%d \t", cur->value);cur = cur->next;}printf("\n");
}
完整代码:(stack.c)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>/* structrue */
typedef struct Node // node structure
{int value;struct Node *next;struct Node *prev;
} LinkNode;/* global variables */
LinkNode *header = NULL; // the header pointer
LinkNode *tail = NULL; // the tailer pointer
int length = 0; // the number of the stack elements/* function prototype */
void push(int data); // add element to the end of the stack
int pop(void); // delete element from the end of the stack
int gettop(void); // show element at the end of the stack
void travel(void); // show element one by one/* main function */
int main(void)
{// cycle input a number until 'q' or non-numeric, add the number to the stackwhile(1) // 循环输入数字,并入栈,输入q退出输入循环{int data = 0, c;printf("if quit,input 'q'. Input a number: ");c = getchar(); // 获取输入的一个字符if(tolower(c) == 'q') break; // 若输入q,则退出输入循环if(c < '0' || c > '9') break; // 输入的不是数字,则退出输入循环while(c != '\n') // 若整数为多位数,通过一位一位计算最终获得多位整数{data *= 10;data += c - 48; // ASCII码表中,0对应码值48c = getchar();}push(data); // 入栈printf("length is %d \n", length); // 输出栈元素个数travel(); // 遍历栈}// when stack not empty,cycle look and delete the top element until input 'n'if(length == 0) exit(-1);char k;printf("if you want to look and delete the top element? (y/n) ");scanf(" %c", &k); // 获取输入的内容while(tolower(k) == 'y' && length != 0) // 循环输入是否查看并删除栈顶元素{printf("top element is %d \n", gettop()); // 输出栈顶元素pop(); // 出栈printf("length is %d \n", length); // 输出栈元素个数travel(); // 遍历栈printf("if you want to look and delete the top element? (y/n) ");scanf(" %c", &k); // 获取下一个输入的内容}
}/* subfunction */
LinkNode * createNode(int data) // create a node
{LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode));if(node == NULL){perror("Memory allocation failed");exit(-1);}node->value = data;node->prev = NULL;node->next = NULL;return node;
}void push(int data) // add element to the end of the stack
{LinkNode *node = createNode(data);if(length == 0){header = node;tail = node;length++;return ;}tail->next = node;node->prev = tail;tail = node;length++;
}int pop(void) // delete element from the end of the stack
{if(length != 0){int top = tail->value;tail->prev->next = NULL;length--;return top;}
}int gettop(void) // show element at the end of the stack
{if(length != 0) return tail->value;
}void travel(void) // show element one by one
{if(length == 0) return ;LinkNode *cur = header;printf("stack elements:");while(cur != NULL){printf("%d \t", cur->value);cur = cur->next;}printf("\n");
}
编译链接: gcc -o stack stack.c
执行可执行文件: ./stack

相关文章:
【数据结构】(C语言):栈
栈: 线性的集合。后进先出(LIFO,last in first out)。两个指针:指向栈顶和栈底。栈顶指向最后进入且第一个出去的元素。栈底指向第一个进入且最后一个出去的元素。两个操作:入栈(往栈尾添加元素…...
c++类成员指针用法
1)C入门级小知识,分享给将要学习或者正在学习C开发的同学。 2)内容属于原创,若转载,请说明出处。 3)提供相关问题有偿答疑和支持。 c中新增类成员指针操作,为了访问方便,他是指…...
[240625] Continue -- 开源 Copilot | Web-Check 网站分析工具 | Story of EOL
目录 Continue -- 开源 CopilotWeb-Check 网站分析工具Web-Check 提供全面的网站分析功能Web-Check 支持多种部署方式:配置选项开发环境Web-Check 使用多种数据源进行分析 Story of EOLASCII 文本中的换行符问题 Continue – 开源 Copilot 让 Continue 和 Ollama 成…...
【Mac】Auto Mouse Click for Mac(高效、稳定的鼠标连点器软件)软件介绍
软件介绍 Auto Mouse Click for Mac 是一款专为 macOS 平台设计的自动鼠标点击软件,它可以帮助用户自动化重复的鼠标点击操作,从而提高工作效率。以下是这款软件的主要特点和功能: 1.自动化点击操作:Auto Mouse Click 允许用户录…...
javaSE知识点整理总结(下)、MySQL数据库
目录 一、异常 1.常见异常类型 2.异常体系结构 3.异常处理 (1)finally (2)throws 二、JDBC 1.JDBC搭建 2.执行SQL语句两种方法 三、MySQL数据库 1.ddl 2.dml 3.dql (1)字符函数 (…...
Perl入门学习
Perl是一种强大的脚本语言,以其灵活性和文本处理能力而闻名,常用于系统管理、Web开发、生物信息学以及数据处理等领域。以下是Perl语言入门学习的一些关键点: ### 1. Perl简介 - **起源与特点**:Perl由Larry Wall在1987年创建&am…...
2024年7月计划(ue5肉鸽视频完成)
试过重点放在独立游戏上,有个indienova独立游戏团队是全职的,由于他们干了几个月,节奏暂时跟不上,紧张焦虑了。五一时也有点自暴自弃了,实在没必要,按照自己的节奏走即可。精力和时间也有限,放在…...
恢复策略(上)-撤销事务(UNDO)、重做事务(REDO)
一、引言 利用前面所建立的冗余数据,即日志和数据库备份,要将数据库从一个不一致的错误状态恢复到一个一致性状态,还需要相关的恢复策略,不同DBMS的事务处理机制所采用的缓冲区管理策略可能不同,发生故障后的数据库不…...
【鸿蒙学习笔记】位置设置
官方文档:位置设置 目录标题 align:子元素的对齐方式direction:官方文档没懂,看图理解吧 align:子元素的对齐方式 Stack() {Text(TopStart)}.width(90%).height(50).backgroundColor(0xFFE4C4).align(Alignment.TopS…...
41.HOOK引擎设计原理
上一个内容:41.HOOK引擎设计原理 在一个游戏里通过hook来完成各种各样的功能,比如hook点是a、b、c,然后a点会有它自己所需要的hook逻辑,b、c也是有它们自己的hook逻辑(hook逻辑指的是hook之后要做的事)&am…...
STM32启动流程 和 map文件的作用
一,启动流程 1. 复位/上电 2. 根据 BOOT0/BOOT1 确定程序从哪个存储位置执行 3. 初始化 SP 及 PC 指针 将 0X08000000 位置的栈顶地址存放在 SP 指针中 将 0x08000004 位置存放的向量地址装入 PC 程序计数器 4. 初始化系统时钟 5. 初始化用户堆栈 6. 进入main函数 二…...
深度解析华为仓颉语言
什么是华为仓颉语言? 华为仓颉语言(Huawei Cangjie Language,HCL)是华为公司推出的一种新型编程语言,旨在解决大规模分布式系统开发中的复杂性问题。仓颉语言以高效、简洁和易用为设计目标,特别适用于云计…...
Android简介-历史、API等级与体系结构
1. Android简介 Android是一种基于Linux内核的自由及开放源代码的操作系统。最初是由安迪鲁宾(Andy Rubin)开发的一款相机操作系统。2005年8月被Google收购。2007年11月,Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统。…...
SpringBoot:使用Spring Batch实现批处理任务
引言 在企业级应用中,批处理任务是不可或缺的一部分。它们通常用于处理大量数据,如数据迁移、数据清洗、生成报告等。Spring Batch是Spring框架的一部分,专为批处理任务设计,提供了简化的配置和强大的功能。本文将介绍如何使用Spr…...
用JQueryUI库在.net MVC中配置datepicker(时间日期控件)
原文参考:如何在MVC中添加jQuery Datepicker_mvc datepicker-CSDN博客 好文章被埋没了,可能和时间发的早有关。 1.首先我们引入JQuery和JQuery UI <!-- ... --> <link rel"stylesheet" href"https://code.jquery.com/ui/1.12…...
算法:链表
目录 链表的技巧和操作总结 常用技巧: 链表中的常用操作 题目一:反转一个单链表 题目二:链表的中间结点 题目三:返回倒数第k个结点 题目四:合并两个有序链表 题目五:移除链表元素 题目六ÿ…...
Redis基础教程(一):redis配置
💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 💝Ὁ…...
短视频矩阵系统:打造品牌影响力的新方式
一、短视频矩阵概念 短视频营销革命:一站式解决策略!短视频矩阵系统是一款专为企业营销设计的高效工具,旨在通过整合和优化众多短视频平台资源,为企业呈现一个全面的短视频营销策略。该系统致力于协助企业以迅速且高效的方式制作…...
品牌推广的三个阶段与核心内容,一篇文章全掌握!
在竞争激烈的市场环境中,品牌推广是企业成功的关键。精心策划的推广策略能够帮助企业在消费者心中树立独特的品牌形象,进而促进销售增长。 作为一家手工酸奶品牌的创始人,目前全国也复制了100多家门店,我理解的品牌推广分为3个阶…...
队列与循环队列
目录 1. 前言: 2. 队列 2.1 队列的概念 2.2 队列的实现 2.3 队列的声明 2.4 队列的初始化 2.5 队列的入队 2.6 队列的出队 2.7 队列获取队头元素 2.8 队列获取队尾元素 2.9 队列获取有效数据个数 2.10 队列判断是否为空 2.11 打印队列 2.12 销毁队列 …...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门  可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
