【数据结构】(C语言):栈

news2024/11/17 15:52:06

栈:

  • 线性的集合。
  • 后进先出(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-1
		length--;
        // 返回原最后节点的值
		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 stack
	while(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对应码值48
			c = 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.coloradmin.cn/o/1864434.html

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

相关文章

前端JS必用工具【js-tool-big-box】学习,根据属性对数组对象进行排序

我们时常遇到这样的场景&#xff0c;服务端给返回的一些数据呢&#xff0c;是json对象是无序的&#xff0c;或者说返回了一个数组&#xff0c;但里面的数据&#xff0c;前端需要根据一些业务需求做排序。 这一小节呢&#xff0c;我们就说一下&#xff0c;利用 js-tool-big-box …

Flask之表单

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 目录 一、HTML表单 二、使用Flask-WTF处理表单 2.1、定义WTForms表单类 2.2、输出HTML代码 2.3、在模板中渲染表单 三、处理表单数据 3.1、提…

武汉星起航:亚马逊全球化布局助力企业拓展国际市场

在当今全球化经济的大背景下&#xff0c;企业如何突破地域限制&#xff0c;将产品推向更广阔的市场&#xff0c;成为了摆在众多企业家面前的重要课题。武汉星起航相信&#xff0c;亚马逊&#xff0c;作为全球最大的在线零售平台之一&#xff0c;以其独特的全球化布局和强大的服…

nuget 包修改默认存放路径

平时使用 nuget packages 时&#xff0c;都是下载包文件到本地。 默认是在C盘&#xff0c;时间一久容量会高达几十个G&#xff0c;这样会拖慢系统运行效率。 这时需要修改包的下载位置。 打开nuget 包配置文件&#xff1a;Nuget.config 路径在 C:\Users\{UserName}\AppData…

一年Java|16K|同程艺龙面经

面经哥只做互联网社招面试经历分享&#xff0c;关注我&#xff0c;每日推送精选面经&#xff0c;面试前&#xff0c;先找面经哥 背景 公司&#xff1a;同程艺龙成都BU,现场部门老大面 之前的同程艺龙电话一面过了&#xff0c;然后通知到同程艺龙成都办公地点现场进行部门老大…

RK3588 Android13 TvSetting 中性能浮窗RAM显示bug

前言 电视产品,客户发现在设备偏好设置->高级设置->性能浮窗菜单里显示的 RAM 大小是错误的, 要求改成正确的,并且屏幕密度修改后,这个浮窗显示不全,也需要一起处理。 效果图 TvSetting 部分修改文件清单 bug 原因在于 Formatter.formatFileSize 这个 API,我们…

ATA-7025高压放大器的优势如何

高压放大器是一类在电子领域中具有重要作用的设备&#xff0c;其主要功能是将输入信号的电压放大到更高的水平。在许多应用中&#xff0c;高压放大器展现出独特的优势&#xff0c;下面将介绍高压放大器的优势以及它们在不同领域的应用。 高压放大器的优势 1.信号驱动能力强 高压…

探索AI世界系列:俗说AI智能体

AI agent&#xff0c;翻译为中文就是AI智能体。 什么是AI智能体呢&#xff1f; 一&#xff0c;GPT对AI智能体的定义 AI智能体&#xff0c;即人工智能体&#xff08;Artificial Intelligence Agent&#xff09;&#xff0c;是具有自主性、学习能力和推理能力的计算机程序。 …

常用的企业级快速传输大文件平台

在当今企业运营中&#xff0c;数据管理成了一项不可或缺的任务。企业每日需处理庞大的数据量&#xff0c;这包括高清视频、大量数据集和复杂的设计图纸等大型文件。然而&#xff0c;传统的文件传输手段&#xff0c;比如通过电子邮件发送附件或使用FTP服务&#xff0c;已经难以满…

【C++】关于虚函数的理解

深入探索C虚函数&#xff1a;原理、应用与实例分析 一、虚函数的原理二、虚函数的应用三、代码实例分析四、总结 在C面向对象编程的世界里&#xff0c;虚函数&#xff08;Virtual Function&#xff09;扮演着至关重要的角色。它不仅实现了多态性这一核心特性&#xff0c;还使得…

充电宝怎么选合适?买充电宝必看选购攻略!好用充电宝推荐

在这个科技飞速发展的时代&#xff0c;手机、平板等电子设备已经成为我们生活中不可或缺的一部分。然而&#xff0c;电池续航问题却常常困扰着我们&#xff0c;特别是在外出旅行、出差或者日常通勤中。这时候&#xff0c;一个靠谱的充电宝就显得尤为重要。但是&#xff0c;面对…

MySQL学习(3):SQL语句之DDL

1.SQL通用语法与分类 &#xff08;1&#xff09;通用语法 &#xff08;2&#xff09;分类 2.DDL 2.1数据库操作 show DATABASES; #查询所有数据库select DATABASE(); #查询当前数据库create DATABASE 数据库名称 [default charest 字符集] [collate 排列规则]; #default cha…

gMLP(NeurIPS 2021)原理与代码解析

paper&#xff1a;Pay Attention to MLPs third-party implementation&#xff1a;https://github.com/huggingface/pytorch-image-models/blob/main/timm/models/mlp_mixer.py 方法介绍 gMLP和MLP-Mixer以及ResMLP都是基于MLP的网络结构&#xff0c;非常简单&#xff0c;关…

太阳初升:born 诞生

在《long long ago》中&#xff0c;我们分析出了首字母l的形象&#xff0c;就是长长的脐带的形象&#xff0c;ong就是脐带冗余蔓连于婴儿肚子上的形象&#xff0c;整个场景为婴儿呱呱坠地脐带尚未剪掉时的情景&#xff0c;而且on通汉字“旦”&#xff0c;通“one”&#xff0c;…

红酒品鉴秘籍:一键解锁味觉宇宙,开启你的味觉探险新纪元

红酒&#xff0c;这种优雅的液体&#xff0c;蕴藏着丰富的口感和层次&#xff0c;每一次的品鉴都是一次味觉的探险。今天&#xff0c;就让我们一起探索红酒品鉴的奥秘&#xff0c;解锁味觉的新世界&#xff0c;而在这个过程中&#xff0c;雷盛红酒将成为我们的向导&#xff0c;…

GraphQL:简介

GraphQL 图片来源&#xff1a; 我们将探索GraphQL 的基础知识&#xff0c;并学习如何使用Apollo将其与 React 和 React Native 等前端框架连接起来。这将帮助您了解如何使用 GraphQL、React、React Native 和 Apollo 构建现代、高效的应用程序。 什么是 GraphQL&#xff1f;…

[深度学习] 生成对抗网络GAN

生成对抗网络&#xff08;Generative Adversarial Networks&#xff0c;GANs&#xff09;是一种由 Ian Goodfellow 等人在2014年提出的深度学习模型Generative Adversarial Networks。GANs的基本思想是通过两个神经网络&#xff08;生成器和判别器&#xff09;的对抗过程&#…

Nodejs使用mqtt库连接阿里云服务器

建项目 命令行输入&#xff1a; npm init 输入项目名&#xff0c;自动化生成项目列表。 6.3 编写代码 新建mqtt_demo_aliyun.js&#xff0c;代码如下&#xff1a; // mqtt_demo_aliyun.jsconst mqtt require("mqtt"); const connectUrl "ws://post-cn-nw**…

展厅设计中需要人性化的地方

1、预留参观空间 展厅空间的布局设计必须尽可能的宽敞&#xff0c;以避免参观人数较多时可能会发生的拥堵&#xff0c;重点展品需要预留较大的展示空间或四面通畅的中心位置&#xff0c;更方便观众从不同角度与方位参观。因为是展厅&#xff0c;不仅代表着企业形象&#xff0c;…

安科瑞光伏并网电表ADL400N-CT双向计量防逆流自带互感器电表-安科瑞 蒋静

1 概述 ADL 系列导轨式多功能电能表&#xff0c;是主要针对于光伏并网系统、微逆系统、储能系统、交流耦合系统等新能源发电系统而设计的一款智能仪表&#xff0c;产品具有精度高、体积小、响应速度快、安装方便等特点。具有对电力参数进行采样计量和监测&#xff0c;逆变器或…