数据结构----链式栈

news2024/11/25 3:43:50

目录

前言

链式栈

操作方式 

1.存储结构

2.初始化

 3.创建节点

 4.判断是否满栈

 5.判断是否空栈

 6.入栈

 7.出栈

8.获取栈顶元素

 9.遍历栈

 10.清空栈

完整代码


前言

        前面我们学习过了数组栈的相关方法,(链接:线性表-----栈(栈的初始化、建立、入栈、出栈、遍历、清空等操作)_灰勒塔德的博客-CSDN博客)那么今天我们就开始学习新的结构栈---链式栈,顾名思义就是通过链表的结构来实现栈的相关方法操作,包括创建、判断空满、出栈、入栈、遍历和清空等操作,下面就一起来看看吧!

链式栈

图示如下:

操作方式 

#include<stdio.h>
#include<stdlib.h>
#define Maxsize 20 //设置最大节点数量

create_node(ElemType data);//创建节点

stack_init(Stack* top);//初始化

isFull(Stack* top);//判断是否满栈

isEmpty(Stack* top);//判断是否空栈

push(Stack* top, ElemType data);//入栈

pop(Stack* top);//入栈

get_stacktop(Stack* top);//获取栈顶元素

show_stack(Stack* top);//遍历栈

clear_stack(Stack* top);//清空栈

1.存储结构

今天实现的是栈的链式储存,也就是俗称“链栈”。由于之前实现过单链表,对于栈的链式存储,二者原理是一样的,只不过在操作上链栈是受限的——仅能在栈顶进行插入和删除!话不多说,先看链栈的存储结构

//数据类型
typedef struct datatype {
	int age;
	char name[10];
	int num;
}ElemType;
//节点
typedef struct node {
	ElemType data;
	struct node* next;
}Node;
//栈顶指示
typedef struct stack {
	int count;	//计数
	Node* point;
}Stack;

2.初始化

初始化就让头指针指向的位置为NULL,节点计数为0

//初始化
void stack_init(Stack* top) {
	top->count = 0;
	top->point = NULL;
}

 3.创建节点

创建节点就通过链表的方式去创建节点,然后把数据值赋予给这个节点

//创建节点
Node* create_node(ElemType data) {
	Node* new_node = (Node*)malloc(sizeof(Node));
	if (new_node) {
		new_node->data = data;
		new_node->next = NULL;
		return new_node;
	}
	else
	{
		printf("ERROR\n");
	}
}

 4.判断是否满栈

判断是否满栈只需要看此时计数是否达到最大容量节点数量即可

//判断是否满
int isFull(Stack* top) {
	if (top->count > Maxsize) {
		printf("The stack is full\n");
		return 1;
	}
	return 0;
}

 5.判断是否空栈

这时候只需要看计数是否为0就行了

//判断是否为空
int isEmpty(Stack* top) {
	if (top->count == 0) {
		printf("The stack is empty\n");
		return 1;
	}
	return 0;
}

 6.入栈

进行入栈的操作类似于链表的成链操作,也就是说把创建好的节点连起来即可,不同的是此时每放入一个节点的时候,栈顶指针top要往栈顶依次往上移动,计数也要+1,代码如下所示:

//入栈
void push(Stack* top, ElemType data) {
	Node* new_node = create_node(data);
	if (new_node&&!isFull(top)) {
		top->count++;
		if (top->count == 1) {//如果入栈是第一个节点的话
			top->point = new_node;
		}
		else
		{
            //以下两个步骤不能调过来!
			new_node->next = top->point;
			top->point = new_node;
		}
	}
	else
		return;
}

 7.出栈

出栈时,先获取到此时栈顶指针指向的位置pop_node,再把栈顶指针向下移动一位,计数减一,然后返回这个元素pop_node即可:

//出栈
Node* pop(Stack* top) {
	Node* pop_node=NULL;
	if (!isEmpty(top)) {
		pop_node = top->point;
		top->point = pop_node->next;
   		pop_node->next = NULL;
		top->count--;
	}
	return pop_node;
}

8.获取栈顶元素

获取栈顶元素不需要出栈,只需要返回栈顶元素即可: 

//获取栈顶元素
Node* get_stacktop(Stack* top) {
	return top->point;
}

 9.遍历栈

遍历栈,从栈顶开始,依次往下遍历输出数据即可:

//遍历栈
void show_stack(Stack* top) {
	Node* cur = top->point;
	while (cur) {
		printf("%d %s %d\n", cur->data.age, cur->data.name, cur->data.num);
		cur = cur->next;
	}
	printf("Print over!\n");
}

 10.清空栈

清空栈,就要去依次把每一个节点的空间给释放掉,然后栈顶往下移动,直到移动到最初始的位置。

//清空栈
void clear_stack(Stack* top) {
	Node* cur;
	while (top->point) {
		cur = top->point;
		top->point = cur->next;
		free(cur);
	}
	printf("Clear successfully!\n");
}

完整代码

#include<stdio.h>
#include<stdlib.h>
#define Maxsize 20 //设置最大节点数量

//链表栈

//数据类型
typedef struct datatype {
	int age;
	char name[10];
	int num;
}ElemType;
//节点
typedef struct node {
	ElemType data;
	struct node* next;
}Node;
//栈顶指示
typedef struct stack {
	int count;	//计数
	Node* point;
}Stack;


//创建节点
Node* create_node(ElemType data) {
	Node* new_node = (Node*)malloc(sizeof(Node));
	if (new_node) {
		new_node->data = data;
		new_node->next = NULL;
		return new_node;
	}
	else
	{
		printf("ERROR\n");
	}
}

//初始化
void stack_init(Stack* top) {
	top->count = 0;
	top->point = NULL;
}


//判断是否满
int isFull(Stack* top) {
	if (top->count > Maxsize) {
		printf("The stack is full\n");
		return 1;
	}
	return 0;
}
//判断是否为空
int isEmpty(Stack* top) {
	if (top->count == 0) {
		printf("The stack is empty\n");
		return 1;
	}
	return 0;
}


//入栈
void push(Stack* top, ElemType data) {
	Node* new_node = create_node(data);
	if (new_node&&!isFull(top)) {
		top->count++;
		if (top->count == 1) {//如果入栈是第一个节点的话
			top->point = new_node;
		}
		else
		{
			new_node->next = top->point;
			top->point = new_node;
		}
	}
	else
		return;
}


//出栈
Node* pop(Stack* top) {
	Node* pop_node=NULL;
	if (!isEmpty(top)) {
		pop_node = top->point;
		top->point = pop_node->next;
		pop_node->next = NULL;
		top->count--;
	}
	return pop_node;
}

//获取栈顶元素
Node* get_stacktop(Stack* top) {
	return top->point;
}

//遍历栈
void show_stack(Stack* top) {
	Node* cur = top->point;
	while (cur) {
		printf("%d %s %d\n", cur->data.age, cur->data.name, cur->data.num);
		cur = cur->next;
	}
	printf("Print over!\n");
}

//清空栈
void clear_stack(Stack* top) {
	Node* cur;
	while (top->point) {
		cur = top->point;
		top->point = cur->next;
		free(cur);
	}
	printf("Clear successfully!\n");
}


int main() {

	Stack top;
	stack_init(&top);//初始化
	ElemType data[4] = { {15,"Jack",01},{16,"Leimu",02},{17,"Lamu",03},{18,"Ajx",04} };
	for (int i = 0; i < 4; i++) {
		push(&top, data[i]);//入栈操作
	}
	show_stack(&top);//遍历栈
	Node* out_data=pop(&top);//出栈操作
	printf("%d %s %d\n", out_data->data.age, out_data->data.name, out_data->data.num);
	clear_stack(&top);//清空栈
}

 以上就是本期的内容,喜欢的给个关注吧!我们下一次再见!

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

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

相关文章

【初阶数据结构】——堆的引入和实现二叉树

目录 前言 一、二叉树的顺序结构及实现 1.1二叉树的顺序结构 1.2堆的结构 二、堆的实现 2.1堆向上调整算法&#xff08;堆的插入&#xff09; 2.2堆向下调整算法&#xff08;堆的删除&#xff09; 2.3建堆的时间复杂度 2.4堆的创建 2.5堆的初始化和空间的销毁 2.6堆…

【数据结构】图的基本概念,图的存储结构(邻接矩阵;邻接表;十字链表;邻接多重表)

欢~迎~光~临~^_^ 目录 1、图的基本概念 2、图的存储结构 2.1邻接矩阵 2.2邻接表 2.3十字链表 2.4邻接多重表 2.5图的四种存储结构的对比 1、图的基本概念 图是由一组节点&#xff08;通常称为顶点&#xff09;和一组连接这些节点的边&#xff08;通常称为边&#xff0…

注册中心的学习

一、什么是注册中心&#xff1f; 注册中心主要有三种角色&#xff1a; 1.1、服务提供者&#xff08;RPC Server&#xff09;&#xff1a; 在启动时&#xff0c;向 Registry 注册自身服务&#xff0c;并向 Registry 定期发送心跳汇报存活状态。 1.2、服务消费者&#xff08;…

Qt5开发及实例V2.0-第七章-Qt图形视图框架

Qt5开发及实例V2.0-第七章-Qt图形视图框架 第7章 Qt 5图形视图框架7.1 图形视图体系结构7.1.1 Graphics View的特点7.1.2 Graphics View的三元素7.1.3 GraphicsView的坐标系统 7.2 【实例】&#xff1a;图形视图7.2.1 飞舞的蝴蝶7.2.2 地图浏览器7.2.3 图元创建7.2.4 图元的旋转…

大数据-kafka学习笔记

Kafka Kafka 是一个分布式的基于发布/订阅模式的消息队列&#xff08;Message Queue&#xff09;&#xff0c;主要应用于大数据实时处理领域。 Kafka可以用作Flink应用程序的数据源。Flink可以轻松地从一个或多个Kafka主题中消费数据流。这意味着您可以使用Kafka来捕获和传输…

Python 图形化界面基础篇:创建顶部菜单

Python 图形化界面基础篇&#xff1a;创建顶部菜单 引言 Tkinter 库简介步骤1&#xff1a;导入 Tkinter 模块步骤2&#xff1a;创建 Tkinter 窗口步骤3&#xff1a;创建顶部菜单栏步骤4&#xff1a;处理菜单项的点击事件步骤5&#xff1a;启动 Tkinter 主事件循环 完整示例代码…

Python 如何把 String 转换为 Json 对象

在我们对 JSON 进行处理的时候&#xff0c;大概率我们会需要把字符串转换为 JSON 对象后才能进行处理。 Python 贴心的使用 json.loads(employee_string)就可以了。 首先需要做的就是导入 JSON 库。 #include json library import json 对现代程序员来说&#xff0c;JSON …

CNC 3D浮雕 Aspire 11.55 Crack

Aspire 提供了功能强大且直观的软件解决方案&#xff0c;用于在 CNC 铣床上创建和切割零件。有用于 2D 设计和计算 2D 刀具路径的工具&#xff0c;例如仿形、型腔加工和钻孔以及 2.5D 刀具路径&#xff0c;包括&#xff1a;V 形雕刻、棱镜雕刻、成型刀具路径、凹槽、 倒角刀具路…

抖音seo矩阵系统开源代码定制部署

抖音SEO底层开发逻辑主要包括以下几个方面&#xff1a; 1. 关键词优化&#xff1a;抖音SEO需要优化关键词&#xff0c;将关键词嵌入短视频标题、描述、标签等地方&#xff0c;提升抖音短视频在搜索引擎中的排名。 2. 标题优化&#xff1a;抖音短视频的标题应简明扼要&#xff…

C/C++满足条件的数的累加 2023年5月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C满足条件的数的累加 一、题目要求 1、编程实现 2、输入输出 二、解题思路 1、案例分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 C/C满足条件的数的累加 2023年5月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 现有n个整数&#x…

【前端面试题】浏览器面试题

文章目录 前言一、浏览器面试问题1.cookie sessionStorage localStorage 区别2.如何写一个会过期的localStorage&#xff0c;说说想法2.如何定时删除localstorage数据2.localStorage 能跨域吗2.memory cache 如何开启2.localstorage的限制2.浏览器输入URL发生了什么2.浏览器如何…

IIC协议详解

目录 1.IIC协议概述 2.IIC总线传输 3.IIC-51单片机应用 1.起始信号 2.终止信号 3.应答信号 4.数据发送 4.IIC-32单片机应用 用到的库函数&#xff1a; 1.IIC协议概述 IIC全称Inter-Integrated Circuit (集成电路总线)是由PHILIPS公司在80年代开发的两线式串行总线&…

进程组.会话.终端

一.进程组.会话.终端概念 1.1进程组 在Linux操作系统中&#xff0c;进程组&#xff08;Process Group&#xff09;是一组进程的集合。进程组内的每个进程都有一个相同的进程组ID&#xff08;PGID&#xff09;。进程组可以用于进行作业控制、信号传递和进程状态管理等操作。 …

大模型+检索增强(RAG、Atlas 和 REPLUG)

https://zhuanlan.zhihu.com/p/651380539 https://github.com/ninehills/blog/issues/97 1. 检索增强生成 RAG 在问答和对话的场景下&#xff0c;通常可以通过检索和生成两种方式得到一个回复。检索式回复是在外部知识库中检索出满意的回复&#xff0c;较为可靠和可控&#…

如何使用 MATLAB 数学编程软件调用 Python 脚本详细教程(每周更新中)

MATLAB 读写操作 在 MATLAB 中&#xff0c;可以使用各种函数来读取和写入文件。其中&#xff0c;filename.txt 是要读取或写入的文件名&#xff0c;r 表示读取模式&#xff0c;w 表示写入模式。fscanf 和 fprintf 函数用于读取和写入文件内容&#xff0c;%c 和 %s 是格式说明符…

Python 通过 stomp 发送消息到 ActiveMQ 的代码

只需要下面简单的几行代码&#xff0c;我们就可以把我们本地数据发送到 ActiveMQ 上面去。 def send_mq(data):hosts [(AMQHOST, AMQPORT)]conn stomp.Connection(host_and_portshosts, auto_content_lengthFalse)conn.connect(usernameAMQUSER, passcodeAMQPASS, waitTrue)…

基于Spring Boot的医院预约挂号系统设计与实现

前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb;…

功夫再高也怕菜刀。多年经验,会独立开发的机器视觉工程师,技术太强,但是找工作能力差劲

功夫再高也怕菜刀&#xff0c;专业的事情交给专业的人去做。 今年7月份中旬的时候&#xff0c;遇到一位老朋友&#xff0c;向我咨询某公司的信息&#xff0c;其实我根本不了解这家公司的情况与实力&#xff0c;向他说了&#xff0c;抱歉&#xff0c;我查下&#xff0c;等我晚上…

怎么把利用paddlepaddle导出的json文件转化为yolo或者voc文件

这两天想偷懒&#xff0c;想让模型先在数据上标一遍&#xff0c;然后我再做修正&#xff0c;主要是图个省事。由于我们的业务主要是利用paddle,模型也是基于paddle推理的&#xff0c;因此即便我对paddle有一万个吐槽但也不得不用它。但在利用paddle保存推理结果文件时&#xff…

Linux Day17 生产者消费者

一、生产者消费者问题概述 生产者 / 消费者问题&#xff0c;也被称作有限缓冲问题。两个或者更多的线程共享同一个缓冲 区&#xff0c;其中一个或多个线程作为 “ 生产者 ” 会不断地向缓冲区中添加数据&#xff0c;另一个或者多个线程作为 “ 消费者 ” 从缓冲区中取走数据。…