【数据结构】(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

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

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

相关文章

Redis服务

目录 1、介绍 1、redis的特点: 2、缓存 2、安装Redis 1、安装单机版redis 2、redis-cli命令参数 3、redis的增删查改命令 4、redis的相关工具 1、介绍 redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库 redis的官网&…

密码学及其应用——专用名词(英语版)

一般术语 1. 密码学 - cryptography 2. 算法 - algorithm 3. 密码系统 - cryptosystem 加密和解密 4. 加密 - encryption 5. 解密 - decryption 6. 加密密钥 - encryption key 7. 解密密钥 - decryption key 8. 数据加密 - data encryption 9. 流密码 - stream ciphe…

摄影师危!AI绘画即将降维打击摄影行业

你还以为AI绘画影响的只是插画师行业吗&#xff1f;错了&#xff0c;摄影行业也即将面临技术洗牌 话不多说&#xff0c;先看一下这几张图 你能一眼看出这是AI画的迪丽热巴吗&#xff1f; 你是不是还以为AI绘画只能画点动漫艺术风格&#xff1f;那你就低估了AI的发展速度&…

java中 前后端不分离的的方法 如何做api接口请求

在传统的Java Web开发中&#xff0c;前后端通常是不分离的&#xff0c;即前端页面和后端API服务是在同一个项目中进行开发和部署的。在这种情况下&#xff0c;我们可以使用Servlet来处理前端的请求&#xff0c;并返回相应的数据。 在本文中&#xff0c;我们将以一个简单的示例…

react开发嵌入react-monaco-editor代码编辑器的方法

Next.js中使用react开发嵌入react-monaco-editor代码编辑器的方法&#xff08;支持语法高亮&#xff09; 安装 (base) PS D:\ai-ui> npm install react-monaco-editoradded 1 package, changed 1 package, and audited 1030 packages in 6s273 packages are looking for f…

《数字图像处理》实验报告五

一、实验任务与要求 实现一个自适应局部降噪滤波器&#xff1b;在一幅测试版图像中加入运动模糊和高斯噪声&#xff0c;产生一幅退化图像&#xff0c;采用 deconvwnr 函数实现逆滤波及维纳滤波。 二、实验报告 &#xff08;一&#xff09;实现一个自适应局部降噪滤波器 1、自…

ajax请求接口不设置请求头可以请求成功,但是设置请求头之后就跨域,已解决

遇到这个问题我们不要着急找后端&#xff0c;先通过控制台看看有没有报错&#xff0c;控制台的列表是不会有这个红色报错的&#xff0c;所以我们要看下图&#xff1a; 点击这个红色&#xff0c;然后在下面会出现一些信息 很明显是这个请求头timestamp的请求头被屏蔽了&#xff…

Linux C语言程序中线程本地存储变量的内存分配和使用

在多线程中&#xff0c;有一种叫线程本地存储&#xff08;Thread-Local Storage&#xff0c;TLS&#xff09;的变量&#xff0c;它是每个线程有且只有一份自己的副本&#xff0c;对于这个线程来说&#xff0c;它是全局变量&#xff0c;可被所有函数共用&#xff1b;因为每个线程…

单机、集群和分布式

目录 1.概述 2.单机服务器 单机版的服务器的性能&#xff0c;设计上的瓶颈&#xff1f; 3.集群 解决瓶颈1&#xff1a; 没有解决瓶颈2&#xff1a; 没有解决瓶颈3&#xff1a; 集群的优点&#xff1f; 集群的缺点&#xff1f; 4.分布式 分布式的优点&#xff1f; 分…

c++笔记提高效率-emplace函数

在C中&#xff0c;标准库容器的emplace方法是一种高效的插入操作&#xff0c;用于在容器中直接构造元素。与insert和push方法相比&#xff0c;emplace方法可以避免不必要的复制或移动操作&#xff0c;因为它直接在容器内部构造元素。下面详细介绍各容器的emplace方法及其用法。…

java常用类(2)

目录 1.String概述 1.1 字符串的不变性 1.2 创建String对象两种方式的区别 1.3 字符串中的构造方法 1.4 字符串判断功能的方法 1.5 字符串获取功能的方法 1.6 字符串转换功能的方法 1.7 字符串替换功能的方法 2.StringBuffer 2.1 构造方法 2.2 插入方法 2.2.1 app…

a-table单元格指定合并以及表格双击编辑以及未填写指定验证功能

文章目录 a-table单元格指定合并以及表格双击编辑以及未填写指定验证功能一、 a-table单元格指定合并1. a-table2. columns3. 图例 二、a-table 表格双击编辑以及未填写验证1. a-table2. js3. 图例 a-table单元格指定合并以及表格双击编辑以及未填写指定验证功能 一、 a-table…

从零开始精通Onvif之加密与认证

&#x1f4a1; 如果想阅读最新的文章&#xff0c;或者有技术问题需要交流和沟通&#xff0c;可搜索并关注微信公众号“希望睿智”。 概述 安全是Onvif规范的核心部分&#xff0c;它涵盖了加密和认证两大领域。在Onvif标准下&#xff0c;安全措施主要包括&#xff1a;设备访问控…

大模型AI技术实现语言规范练习

人工智能技术可以为语言规范练习提供多种有效的解决方案&#xff0c;帮助学习者更有效地掌握语言规范。以下是一些常见的应用场景。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 智能纠错 利用自然语言处理技术&#xff0c;可以…

DC/AC电源模块一种效率与可靠性兼备的能源转换解决方案

DC/AC电源模块都是一种效率与可靠性兼备的能源转换解决方案 DC/AC电源模块是一种能够将直流电源&#xff08;DC&#xff09;转换为交流电源&#xff08;AC&#xff09;的设备。它在现代电子设备中扮演着非常重要的角色&#xff0c;因为许多设备需要交流电源才能正常运行。无论…

树形结构的勾选、取消勾选、删除、清空已选、回显、禁用

树形结构的勾选、取消勾选、删除、清空已选、回显、禁用 基本页面&#xff1a; 分为上传文件和编辑的页面 代码实现要点&#xff1a; 上传文件页面&#xff1a; 点开选择范围弹窗&#xff0c;三个radio单选框都为可选状态&#xff0c;默认显示的是第一个单选框&#xff08;按…

开源C++版AI画图大模型框架stable-diffusion.cpp开发使用初体验

stable-diffusion.cpp是一个C编写的轻量级开源类AIGC大模型框架&#xff0c;可以支持在消费级普通设备上本地部署运行大模型进行AI画图&#xff0c;以及作为依赖库集成的到应用程序中提供类似于网页版stable-diffusion的功能。 以下基于stable-diffusion.cpp的源码利用C api来…

人工智能的未来:畅想智能新时代

人工智能正在改变我们的世界&#xff0c;它将带我们走向何方&#xff1f; 著名神经科学家、Numenta 公司创始人杰夫•霍金斯 Jeff Hawkins 在其著作《人工智能的未来》中&#xff0c;描绘了一幅人工智能发展的光明图景。他认为&#xff0c;人工智能将超越人类智能&#xff0c;…

理解Gobrs-Async相对于CompletableFuture的优势

Gobrs-Async框架针对复杂应用场景下的异步任务编排&#xff0c;提供了一些传统Future或CompletableFuture所不具备的特性和能力&#xff0c;以下是它能够解决的问题和相对于CompletableFuture的优势&#xff1a; 1. **全链路异常回调**&#xff1a; - Gobrs-Async允许为任务…

关于地图点击的操作

_this.map.dragging.disable(); //地图拖拽 _this.map.doubleClickZoom.disable(); //禁止双击放大地图 _this.map.scrollWheelZoom.disable(); //禁止鼠标滑轮滚动放大缩小地图 _this.map.dragging.enable(); //e…