c语言数据结构(5)——栈

news2025/5/21 8:18:54

欢迎来到博主的专栏——C语言数据结构
博主id:代码小豪

文章目录

    • 栈的顺序存储结构
      • 栈的插入
      • 空栈的初始化
      • 栈的删除
      • 判断空栈
      • 读取栈顶元素数据
    • 实现顺序栈的所有代码
    • 栈的链式存储结构
      • 链式栈的初始化
      • 链式栈的入栈操作
      • 链式栈的出栈操作
    • 实现链式栈的所有代码

栈是一个特殊线性表,其只能在表尾进行数据的插入与删除,进行数据的插入与删除的一端称为栈顶 (TOP)。

我们可以将栈想象成一个酸菜坛子,往坛子中开始放菜的时候,坛中的酸菜是从底部开始增加的。

当坛子放满酸菜后,我们开坛取出酸菜,酸菜会从顶部开始减少。

栈的顺序存储结构

前面提到了,栈是一个特殊的线性表,所以栈的储存形式也可以像线性表一样分为两种,一种为顺序存储结构的栈(顺序栈)。

既然顺序栈是用顺序结构实现的,那么就可以用数组来实现顺序栈。

顺序栈的结构声明如下:

typedef int SDataType;
typedef struct SeqStack
{
	SDataType val[MAXSIZE];
	int TOP;
}SeqStack;

栈的插入

从栈顶插入数据的操作被称为入栈(PUSH)
在这里插入图片描述

将数据插入栈顶的位置,然后栈顶的位置往上挪动一位,用于下一次入栈操作。

为空时,栈顶的位置为0.
在这里插入图片描述

还有一种空栈的表示方法,由于数组中第一个元素的下标是0,但是空栈就代表着0下标处没有元素,所以空栈时,栈顶的位置为-1.
在这里插入图片描述
如果用这个方法表示的空栈,在插入数据时应该先让栈顶往上一步,再插入数据。
在这里插入图片描述

void StackPush(SeqStack* stack, SDataType e)
{
	if (stack->TOP == MAXSIZE)
	{
		perror("stack overflow\n");
		return;
	}
	stack->val[stack->TOP] = e;
	stack->TOP++;
}

空栈的初始化

将一个新生成的栈传入函数进行初始化,初始化的方法根据入栈的形式而定(TOP为0或TOP为-1)

以前者为例,空栈的初始化的函数为

void StackInit(SeqStack* stack)
{
	stack->TOP = 0;
}

栈的删除

从栈顶删除数据的操作称为出栈(POP)
在这里插入图片描述

出栈的方式很简单,我们不用将当前栈顶的数据进行处理,只需要将TOP的位置往下移动一格就行。

要注意当栈为空栈时的特殊情况,当栈为空栈时,出栈的操作会导致TOP位于非法的位置,当下次进行入栈操作时,就会发生数组越位的错误发生。

判断空栈

判断空栈的条件需要按照初始化时,栈顶的位置为准,以前者为例

bool StackEmpty(SeqStack* stack)
{
	return stack->TOP == 0;
}

如果TOP为0,那么该函数返回值为true。反之为false。

出栈的函数需要调用判断空栈的函数,如下:

void StackPop(SeqStack* stack)
{
	if (StackEmpty(stack))
	{
		perror("stack is empty\n");
		return;
	}
	stack->top--;
}

读取栈顶元素数据

SDataType StackTop(SeqStack* stack)
{
	return stack->val[stack->top - 1];
}

实现顺序栈的所有代码

typedef int SDataType;
typedef struct SeqStack
{
	SDataType val[MAXSIZE];
	int top;
}SeqStack;

void ListStackInit(ListStack* stack)
{
	assert(stack);
	stack->top = NULL;
	stack->lenth = 0;
}

void ListStackPush(ListStack* stack, LDataType e)
{
	StackNode* newnode = malloc(sizeof(StackNode));
	assert(newnode);
	newnode->val = e;
	newnode->next = stack->top;
	stack->top = newnode;
	stack->lenth++;
}

bool ListStackEmpty(ListStack* stack)
{
	return stack->top == NULL;
}

void ListStackPop(ListStack* stack)
{
	if (!ListStackEmpty(stack))
	{
		perror("stack is empty\n");
		return;
	}
	StackNode* del = stack->top;
	stack->top = stack->top->next;
	free(del);
}

LDataType ListStackTop(ListStack* stack)
{
	assert(stack);
	return stack->top->val;
}

栈的链式存储结构

栈既然是线性表,就可以用链表的形式来实现。

栈是从表尾进行插入和删除,链表可以用尾插\尾删的方法实现出栈和入栈(?)。

在这里插入图片描述

在这里插入图片描述
可以发现,使用尾删法是不能实现出栈操作的,因为单链表不能将TOP回到上一个数据的位置。

为了解决这个问题,我们将TOP的位置变为链表头,将入栈和出栈的操作用头插\头删法来实现。

在这里插入图片描述
在这里插入图片描述
链式栈的结构类型如下:

typedef int LDataType;
typedef struct StackNode
{
	LDataType val;
	struct StackNode* next;
}StackNode;

typedef struct ListStack
{
	StackNode* top;
	int lenth;
};

链式栈的初始化

链式栈的初始化如下

void ListStackInit(ListStack* stack)
{
	assert(stack);
	stack->top = NULL;
	stack->lenth = 0;
}

链式栈的入栈操作

链式栈入栈使用头插法。代码如下:

void ListStackPush(ListStack* stack, LDataType e)
{
	StackNode* newnode = malloc(sizeof(StackNode));
	assert(newnode);
	newnode->val = e;
	newnode->next = stack->top;
	stack->top = newnode;
	stack->lenth++;
}

链式栈的出栈操作

考虑到链表空栈无法出栈,所以先定义一个判断空栈的函数

bool ListStackEmpty(ListStack* stack)
{
	return stack->top == NULL;
}

链式栈出栈使用头删法。代码如下:

void ListStackPop(ListStack* stack)
{
	if (ListStackEmpty(stack))
	{
		perror("stack is empty\n");
		return;
	}
	StackNode* del = stack->top;
	stack->top = stack->top->next;
	free(del);
}

实现链式栈的所有代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int LDataType;
typedef struct StackNode
{
	LDataType val;
	struct StackNode* next;
}StackNode;

typedef struct ListStack
{
	StackNode* top;
	int lenth;
}ListStack;

void ListStackInit(ListStack* stack);
void ListStackPush(ListStack* stack,LDataType e);
void ListStackPop(ListStack* stack);
bool ListStackEmpty(ListStack* stack);
LDataType ListStackTop(ListStack* stack);

void ListStackInit(ListStack* stack)
{
	assert(stack);
	stack->top = NULL;
	stack->lenth = 0;
}

void ListStackPush(ListStack* stack, LDataType e)
{
	StackNode* newnode = malloc(sizeof(StackNode));
	assert(newnode);
	newnode->val = e;
	newnode->next = stack->top;
	stack->top = newnode;
	stack->lenth++;
}

bool ListStackEmpty(ListStack* stack)
{
	return stack->top == NULL;
}

void ListStackPop(ListStack* stack)
{
	if (ListStackEmpty(stack))
	{
		perror("stack is empty\n");
		return;
	}
	StackNode* del = stack->top;
	stack->top = stack->top->next;
	free(del);
}

LDataType ListStackTop(ListStack* stack)
{
	assert(stack);
	return stack->top->val;
}

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

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

相关文章

[微服务]Eureka注册中心

目录 1、引言 2、Eureka的结构和作用 2.1、图解 2.2、几个重要问题⭐ 3、搭建eureka-server 3.1.创建eureka-server服务 3.2、引入eureka依赖 3.3、编写启动类 3.4、编写配置文件 3.5、启动服务 4、服务注册(user) 4.1、引入依赖 4.2、配置文件 4.3、启动多个use…

python--练习题

1.python是一种&#xff08; &#xff09;类型的编程语言 A.机器语言 B.解释 C.编译 D.汇编语言 答案&#xff1a;B 2.python语言print(中国&#xff0c;你好)的输出是&#xff08;&#xff09; A.(中国&#xff0c;你好&#xff09; B.中国&#xff0c;你好 C.中国&#xff0c…

【前端素材】推荐优质后台管理系统网页Star admin平台模板(附源码)

一、需求分析 1、系统定义 后台管理系统是一种用于管理和控制网站、应用程序或系统的管理界面。它通常被设计用来让网站或应用程序的管理员或运营人员管理内容、用户、数据以及其他相关功能。后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;通常由管理员使…

吴恩达机器学习全课程笔记第五篇

目录 前言 P80-P85 添加数据 迁移学习 机器学习项目的完整周期 公平、偏见与伦理 P86-P95 倾斜数据集的误差指标 决策树模型 测量纯度 选择拆分方式增益 使用分类特征的一种独热编码 连续的有价值特征 回归树 前言 这是吴恩达机器学习笔记的第五篇&#xff0c…

Redis 的 介绍 及 使用

redis 简介 简单来说 redis 就是一个数据库&#xff0c;不过与传统数据库不同的是 redis 的数据是存在内存中的&#xff0c;所以读写速度非常快&#xff0c;因此 redis 被广泛应用于缓存方向。另外&#xff0c;redis 也经常用来做分布式锁。redis 提供了多种数据类型来支持不同…

springboot3.x 以上,官方不建议使用spring.factories

springboot2.7.x 以上,官方不建议使用spring.factories 最近公司项目升级.需要将springcloud/springboot版本升级到2.7.x以上,再升级的过程中遇到了太多的问题.总结在了如下文章中: springboot艰难版本升级之路!! springboot 2.3.x版本升级到2.7.x版本 这篇文章就重点是梳理一…

npm digital envelope routines::unsupported

问题描述&#xff1a;npm运行命令报错&#xff1a;digital envelope routines::unsupported 原因&#xff1a;node版本过高 解决方案&#xff1a;在运行命令之前加上 SET NODE_OPTIONS--openssl-legacy-provider && SET NODE_OPTIONS--openssl-legacy-provider &&a…

vSphere资源管理

一 内存、CPU、资源池和vApp 内存部分&#xff1a; 关联VM内存 我们可以超额的关联内存给VM。例如&#xff1a;ESXI物理主机内存只有8G&#xff0c;但我们可以给三个VM都分配4G内存。 2.ESXI四大高级内存控制技术 a.Page sharing&#xff08;透明的页面共享&#xff09; 虚…

PYTHON 自动化办公:压缩图片(PIL)

1、介绍 在办公还是学习过程中&#xff0c;难免会遇到上传照片的问题。然而照片的大小限制一直都是个问题&#xff0c;例如照片限制在200Kb之内&#xff0c;虽然有很多图像压缩技术可以实现&#xff0c;但从图像处理的专业来说&#xff0c;可以利用代码实现 这里使用的库函数是…

【深度学习笔记】5_4 池化层

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 5.4 池化层 回忆一下&#xff0c;在5.1节&#xff08;二维卷积层&#xff09;里介绍的图像物体边缘检测应用中&#xff0c;我们构造卷…

python 使用curl_cffi 绕过jax3指纹-Cloudflare 5s盾

现在越来越多的网站已经能够通过JA3或者其他指纹信息&#xff0c;来识别你是不是爬虫了。传统的方式比如换UA&#xff0c;加代理是没有任何意义了&#xff0c;所以这个时候我们就需要使用到curl_cffi 了。 1.TLS 指纹是啥&#xff1f; 在绝大多数的网站都已经使用了 HTTPS&am…

【YOLO v5 v7 v8 小目标改进】ODConv:在卷积核所有维度(数量、空间、输入、输出)上应用注意力机制来优化传统动态卷积

ODConv&#xff1a;在卷积核所有维度&#xff08;数量、空间、输入、输出&#xff09;上应用注意力机制来优化传统的动态卷积 提出背景传统动态卷积全维动态卷积效果 小目标涨点YOLO v5 魔改YOLO v7 魔改YOLO v8 魔改 论文&#xff1a;https://openreview.net/pdf?idDmpCfq6Mg…

电商小程序10分类管理

目录 1 分类数据源2 搭建功能3 创建变量读取数据4 绑定数据总结 本篇我们介绍一下电商小程序的分类管理功能的开发&#xff0c;先看我们的原型图&#xff1a; 在首页我们是展示了四个分类的内容&#xff0c;采用上边是图标&#xff0c;下边是文字的形式。使用低代码开发&#…

Redis大数据统计

文章目录 一. 相关面试题1. 面试题一2. 面试题二 二. 统计的类型1. 聚合统计2. 排序统计3. 二值统计4. 基数统计 三. Hyperloglog1. 专业名词2. Hyperloglog使用3. Hyperloglog原理4. Hyperloglog案例 四. GEO1. 面试题2. GEO使用3. GEO案例 五. BitMap1. 面试题2. BitMap使用 …

Java+SpringBoot+Vue:招生宣传的全栈解决方案

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

《汇编语言》- 读书笔记 - 第13章-int 指令

《汇编语言》- 读书笔记 - 第13章-int 指令 13.1 int 指令13.2 编写供应用程序调用的中断例程中断例程&#xff1a;求一 word 型数据的平方主程序中断处理程序执行效果 中断例程&#xff1a;将一个全是字母&#xff0c;以0结尾的字符串&#xff0c;转化为大写主程序中断处理程序…

中央处理器CPU中的技术

1 知识加油站 1.1 cpu 指令的执行过程 取指&#xff1a;cpu 获取 程序计数器 中存放的指令地址。读取内存中此地址对应指令并存入指令寄存器译码&#xff1a;指令译码器&#xff0c;解析指令运行&#xff1a;算数逻辑单元计算回写&#xff1a;将执行结果写入对应位置 2. cpu…

如何使用ShellSweep检测特定目录中潜在的webshell文件

关于ShellSweep ShellSweep是一款功能强大的webshell检测工具&#xff0c;该工具使用了PowerShell、Python和Lua语言进行开发&#xff0c;可以帮助广大研究人员在特定目录中检测潜在的webshell文件。 ShellSweep由多个脚本模块组成&#xff0c;能够通过计算文件内容的熵来评估…

xsslabs第四关

测试 "onclick"alert(1) 这与第三关的代码是一样的&#xff0c;但是每一关考的点是不一样的所以我们看一下源代码 <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv"content-type" content"text/html;ch…

C++string类讲解

大家好鸭 见字如面&#xff0c;已经有好久没有写文章了&#xff0c;这段时间忙着学习&#xff0c;也忙着玩&#xff0c;所以停更了一段时间 今天让我们来谈一谈关于C中的string类 什么是string类&#xff1f; 在c语言中我们操作字符串往往采用指针&#xff0c;这样的访问方式并…