数据结构----链式栈

2023-11-18

目录

前言

链式栈

操作方式 

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);//清空栈
}

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构----链式栈 的相关文章

  • 返回 Web 浏览器中 HtmlElement 的所有属性

    我需要从我的网络浏览器获取所有属性 当前 我正在使用 GetAttribute 但这样 我需要知道属性的名称 想象一下我不知道我的网络浏览器中有什么 我的 C 代码 StringWriter strWriter new StringWrit
  • 不带()的sizeof有什么作用? [复制]

    这个问题在这里已经有答案了 作者是这个问题 https stackoverflow com questions 18898410 2 dimensional array simple understanding当我问他什么时 他只是取笑我s
  • ASP.NET Core 3:如何在自定义库中引用 3.0.0 程序集?

    我看到引用的应用程序Microsoft AspNetCore App框架 又称为 ASP NET Core 3 0 使用程序集中的类型Microsoft AspNetCore Mvc Abstractions Version 3 0 0 0
  • 从 GetLastError() 函数返回的错误代码中获取文本

    我需要获取从 GetLastError 函数获得的错误代码的文本 我看到了一些示例 但我想要一个获取代码并返回字符串的函数 谢谢大家 我猜你想要这样的东西 DWORD dwLastError GetLastError TCHAR lpBuf
  • 通过 Office API 将多个 Word 文档保存为 HTML

    我有大量的Word文档需要解析 由于它们都是从同一个模板创建的 我认为最好的方法是将它们保存为 HTML 文件并解析 HTML 本身 虽然将单个 Word 文档保存为 HTML 相当容易 但我还没有找到从 Word 内部执行批量过程的方法
  • 尝试使用指向 ODBC DSN 的连接字符串时出现关键字不支持异常

    我为我的 Asp Net MVC 应用程序的数据库访问创建了一个 ODBC DSN 主要原因之一是它可以轻松地将数据库凭据 例如服务器地址 端口 用户名和密码 置于源代码控制之外 而不会妨碍我的发布能力 所以我将连接更改为DSN MyDSN
  • OpenGL 着色器不与着色器程序链接

    我正在尝试使用 GLFW GLEW 添加着色器 我收到一个错误 指出着色器已加载 但它们没有有效的对象代码 这是我用于加载着色器的代码 class SHADER public void LoadShaders const char vert
  • 运行时动态转换

    有没有一种方法可以在运行时动态转换 如以下伪代码 foreach DataRow row in table Rows foreach DataColumn col in table Columns if row col DBNull Val
  • 更改 RabbitMQ 队列中的参数

    我有一个 RabbitMQ 队列 最初声明如下 var result channel QueueDeclare NewQueue true false false null 我正在尝试添加死信交换 因此我将代码更改为 channel Exc
  • 私有方法和属性的 JetBrains Rider C# 命名风格

    我想将私有方法的首字母设为小写 将公共方法的首字母设为大写 然而 在 Rider 中 C 命名风格下似乎只有一个选项可以应用所有方法 属性和事件 告诉 Rider 仅对私人使用不同约定的最佳方式是什么 也可以看看 私有方法和属性的 ReSh
  • 将数据表传递给存储过程

    我有一个用 C 创建的数据表 using DataTable dt new DataTable dt Columns Add MetricId typeof int dt Columns Add Descr typeof string dt
  • 结构体前向声明编译失败

    我有以下代码 但编译器说 sender wrapper 未定义 即使我向前声明了它 我不能对结构进行前向声明吗 用VS2003编译 struct send wrapper struct IPSend IPSend IPSend const
  • 在函数内部使用时,c 数组大小会发生变化

    我有这段代码 include
  • ThemeInfo 属性有什么用?

    每当我创建新的 WPF 应用程序或 WPF 用户控件库时 AssemblyInfo cs文件包含以下属性 assembly ThemeInfo ResourceDictionaryLocation None where theme spec
  • 如何检查单元格是否为空 (Excel\VisualC#)

    我的目标是逐行检查Sheet1为了发现有多少行 所以我放了一个 do while 一旦到达空白单元格就应该停止 Example 第 1 行数据第2行数据第3行数据第4行数据第5行数据 第 6 行数据第7行数据 在本例中 我只需要前 5 行
  • thread_local成员变量构造

    我遇到了 thread local 的一些奇怪行为 不确定我是否做错了什么或者这是一个 GCC 错误 我有以下最小重现场景 include
  • 如何通过列名检查MySqlDataReader中的NULL?

    我怎样才能检查NULL开放的价值MySqlDataReader 以下不起作用 它总是击中else if rdr GetString timeOut null queryResult Egresstime Logged in else que
  • opencv中矩阵的超快中值(与matlab一样快)

    我正在 openCV 中编写一些代码 想要找到一个非常大的矩阵数组 单通道灰度 浮点数 的中值 我尝试了几种方法 例如对数组进行排序 使用 std sort 和选择中间条目 但与 matlab 中的中值函数相比 它非常慢 准确地说 在 ma
  • 如何只应用一种 clang-format 操作?

    我想用clang 格式调整我的评论 但仅此而已 选项是 AlignTrailingComments bool 但是当我运行以下命令时 clang format 3 6 i style AlignTrailingComments true
  • 检测 Windows 重新启动是否是由于 Windows 更新造成的

    我的电脑上的一些应用程序一直在检测 Windows 更新是否重新启动 这是可以观察到的 因为它们会在 Windows 更新自动重启后重新启动 这非常有帮助 因为这些应用程序会重新加载更改 甚至unsaved更改或恢复选项卡 如果是浏览器 执

随机推荐

  • 软件质量属性

    质量特性 质量子特性 功能性 适宜性 准确性 互用性 依从性 安全性 可靠性 成熟型 容错性 可恢复性 可用性 可理解性 易学性 可操作性 效率 时间特性 资源特性 可维护性 可分析性 可修改性 稳定性 可测试性 可移植性 适应性 易安装性
  • Backtrader量化&回测10——取消预加载,读取自定义的可迭代数据

    文章目录 各模块解释 1 获取K线数据 2 可迭代数据类 3 策略模块 示例代码 从这一部分开始 我们将不会再聚焦于基本的操作细节上 而是更多的做一些有特点的修改 or 魔改 这篇博客记录了 不进行预加载数据 而是实时加载数据的操作 各模块
  • 靠着“反转”设计,这些短视频火了

    不知从何时开始 在那些爆火的短视频中 出现了这样一类作品 开头看似平平无奇 一切正常 突然惊现神转折 给了观众一个措手不及 而这种措手不及也大大提升了观众对此类视频的强烈兴趣 在短短15s到60s的体量内 反转 设计凭借出人意料的戏剧化特性
  • 华为云鲲鹏云服务器系列的规格,鲲鹏云服务器系列规格

    鲲鹏云服务器系列规格 内容精选 换一换 华为云帮助中心 为用户提供产品简介 价格说明 购买指南 用户指南 API参考 最佳实践 常见问题 视频帮助等技术文档 帮助您快速上手使用华为云服务 介绍在执行扩容操作有一定的限制 用户需要在扩容前充分
  • C# Newtonsoft.Json object 转 json 为空

    问题 使用 Newtonsoft Json 框架 object 转 json 发现用 internal 修饰的属性 不能被转json JsonConvert SerializeObject obj 例如 internal sealed cl
  • 07Vue3-Vuex中计算数学getters应用

    getters Home vue
  • java动漫_求java做动画代码

    展开全部 import java awt Canvas import java awt Color import java awt Dimension import java awt EventQueue import java awt F
  • VMware无法连接网络

    运行VMware之后 使用 ip addr 指令查看ip地址的时候发现没有ip地址 打开任务管理器 gt 服务 找到 VMnetDHCP 和 VMware NAT Service 右击运行 配置完之后重启网络
  • 中国C-V2X通讯标准应用层标准介绍

    前言 2017年9月18日 中国智能网联汽车产业创新联盟携手重庆长安汽车 通用汽车 清华大学等单位发布了我国第一部V2X应用层团体标准 合作式智能运输系统 车用通信系统应用层及应用数据交互标准 T CSAE 53 2017 该标准的发布填补
  • Unity C# OnTriggerEnter()理解

    网上看了不少文档 但是实在是看不太明白 所以就索性花了一个晚上 终于算是弄明白了OnTriggerEnter 函数 自认为我理解的没错 如果有错误的地方 还烦请指正 举例说明 ColliderTest cs代码 void OnTrigger
  • JQuery扩展 — div大小改变触发事件

    以下为js代码 function window undefined var elems jq resize resize extend resize timeout id str setTimeout setTimeout str resi
  • mySql查看和修改字符编码

    http blog sina com cn s blog 70e79b050101dhnx html MySQL的默认编码是Latin1 不支持中文 要支持中午需要把数据库的默认编码修改为gbk或者utf8 1 需要以root用户身份登陆才
  • Inno Setup 如何让生成的setup.exe文件有管理员权限

    首先 在 Setup 段 PrivilegesRequired admin 然后 找到INNO安装目录下的SetupLdr e32文件 将程序中的Manifest更改一下 用reshacker这类工具改 这样运行程序的时候 Windows
  • AI实战营第二期 笔记5——MMPretrain代码课

    文章目录 摘要 MMPreTrain实战 安装 推理 OR 使用API 数据集 训练与测试 微调 摘要 MMPretrain 是一个全新升级的预训练开源算法框架 旨在提供各种强大的预训练主干网络 并支持了不同的预训练策略 MMPretrai
  • angular2 router中的路由跳转navigate

    navigate是Router类的一个方法 主要用来跳转路由 函数定义 navigate commands any extras NavigationExtras Promise
  • 人工智能(crawler)—— 爬虫综合

    目录 内容简介 第一章 爬虫简介 1 1 什么是网络爬虫 1 1 1 爬虫的简单定义 1 1 2 爬虫的分类 1 2 为什么需要爬虫 1 2 1 爬虫的用途 1 2 2怎么做爬虫 第二章 爬虫的基本常识 2 1 爬虫的合法性问题 2 2 爬
  • QT按钮显示和隐藏

    创建GroupBox 将按钮放置进去 ui groupBox gt setGeometry 100 100 150 50 int x ui groupBox gt geometry x int y ui groupBox gt geomet
  • Flutter 层叠布局组件

    文章目录 Flutter 层叠布局组件 简述 Stack 基本使用 fit属性 alignment属性 Stack Positioned IndexedStack Flutter 层叠布局组件 简述 Stack组件可以将子元素叠加显示 类似
  • 解放原画师!Wav2Lip 用 AI 听音同步人物口型

    By 超神经 内容提要 眼见为实 在 AI 技术面前已经失效了 换脸 对口型的技术层出不穷 效果越来越逼真 今天要介绍的 Wav2Lip 模型 只需一段原始视频与目标音频 就可将其合二为一 关键词 唇形同步 语音信号 近几年 好莱坞动画屡屡
  • 数据结构----链式栈

    目录 前言 链式栈 操作方式 1 存储结构 2 初始化 3 创建节点 4 判断是否满栈 5 判断是否空栈 6 入栈 7 出栈 8 获取栈顶元素 9 遍历栈 10 清空栈 完整代码 前言 前面我们学习过了数组栈的相关方法 链接 线性表 栈 栈