9-数据结构-栈(C语言版)

数据结构-栈(C语言版)

目录

数据结构-栈(C语言版)

1.栈的基础知识

1.入栈,出栈的排列组合

        情景二:Catalan函数(计算不同出栈的总数)

2.栈的基本操作

        1.顺序存储

        (1)顺序栈-定义:

        (2)顺序栈-栈空

        (3)顺序栈-入栈

        (4)顺序栈-出栈以及取值

        (5)共享栈

        2.链式存储

        (1)链栈-定义:

        (2)链栈-入栈

        (3)链栈-出栈

        (4)链栈-打印栈

总代码如下:(可运行)



1.栈的基础知识

 简介:

        栈是后进先出,逻辑上相当于一个桶,只能从顶端操作。

1.入栈,出栈的排列组合

        情景一:已知入栈序列,求出栈序列的可能。

        方法:先看出栈序列最左边,之后按个排序,拿着这个出栈的数,取入栈序列找它前面的可能,之后再回到选择取对比。

        例如:a,b,c,d,e,f依次进栈,求出栈的可能不是哪个:一般为选择题,从选项中的出栈序列最左边开始找,如fedcba,若f先出栈,则f后面的次序一定是...e..d..c..b..a,发现符合,再看第二个fe,e出栈后,后面出栈的可能为d..c..b..a..f符合,再看第三个fed,d出栈后,可能出栈的有:c..b..a..,符合,直到最后都符合。所以这个出栈对。又例如:出栈序列cabdef,先c,c先出栈,后面可能..b..a,结果选项出栈为..a..b,次序反了,所以这个就不是,

        情景二:Catalan函数(计算不同出栈的总数)

        n个元素依次进栈,可以得到多少种不同的出栈序列?

        Catalan函数公式:\frac{C_{2n}^{n}\textrm{}}{n+1},别问为啥,问就是,记着就行了。代入,即可得到结果,

2.栈的基本操作

 简介:按照不同存储方式,分为顺序存储和链式存储。

        1.顺序存储

        简介:顺序存储即定义一个结构体,里面有一个存储数据的数组,和一个记录栈顶的变量top。

如图:

        (1)顺序栈-定义:

#define MaxSize 50  //最大容量
typedef struct
{
	int data[MaxSize];//存储栈数据的一维数组
	int top;	//表示栈顶的变量top
}SqStack;

        (2)顺序栈-栈空

        简介:要看清楚栈空时,top指向哪里,不同的指向,进栈出栈的操作就不一样,不过,一般画图,就明白了。

        初始化:InitStack(&s) 即栈空

//初始化
//因为想要改变结构体内的值,实参形参都变化,所以传栈s的地址进来,栈*S指针接收
void InitStack(SqStack *s)  
{
	s->top=-1;
} 

要看清top栈空的条件时什么,再进行相应的初始化。

初始化之后,便是验证是否栈空StackEmpty(s)

//判断是否栈空
void StackEmpty(SqStack s)
{
	if(s.top== -1)
	return 1;
}

        (1)s.top==-1,表示栈空

        

        此时,我的数组要想赋值,肯定需要top先加1,定位到数组第一个元素,随后再赋值。因此当top==-1表示空时,top先++,随后再赋值,top始终指向栈顶位置

         (2)s.top==0,表示栈空

         此时,我的数组要想赋值,top已经指向数组第一个位置,可以直接赋值,之后再top++。因此当top==0表示空时,先赋值,再top++,top始终指向栈顶位置的下一个位置

        (3)顺序栈-入栈

        入栈即从外边,进桶里,此时要考虑上溢情况,避免数组容量不够。上溢可通过一定的策略优化,减少上溢的情况

               代码如下:SqPush(&s,x);

//入栈
void SqPush(SqStack *s,int x)
{
	if(s->top == MaxSize-1)
	{
		exit(-1);//栈满,退出 
	}
	s->top++;
	s->data[s->top]=x;	
} 

        (4)顺序栈-出栈以及取值

        出栈则是从顶部出取,只可操作一端。出栈时考虑下溢,下溢时逻辑错误,不取决于策略的优化

代码如下:

//出栈
void Sqpush(SqStack *s,int *n)
{
	if(s->top==-1)
		exit(-1); 
		
	*n=s->data[s->top];
	s->top--;
} 

        (5)共享栈

        简介:当顺序栈一次性申请的数组空间太大时,会造成空间浪费,最后还有好多空间没有用。因此对于两个类型相同的栈,我们可以让他们在同一个栈中,进行存取。分别从左右两端进行入栈,中间为栈底。

        共享栈的好处:节省存储空间,降低发生上溢的可能

 栈空:top0==-1,top1==MaxSize

 栈满:他俩碰头了,top0+1=top1

共享栈了解思想即可。

        2.链式存储

         简介:采取单链表形式实现的栈,为栈的链式存储,只不过这里的单链表,只能从表头进行插入和删除。

        采用链栈的优点:便于多个栈共享存储空间,提高效率,不存在上溢情况,插入删除更方便。

        特殊约定:采用单链表实现的栈,默认没有头节点,头指针直接指向第一个实际结点,都在表头进行操作。

        (1)链栈-定义:

//栈的链式存储
typedef struct StackNode
{
	int data;
	struct StackNode *next;	
	
}StackNode; 

        (2)链栈-入栈

思路:插入结点,插入结点先主动,P结点的指针与,存储原第一个结点的地址,即头节点所存的地址。之后更新头指针,把p结点地址赋值给头指针phead

 代码如下:

//入栈
StackNode*  StackNodepush(StackNode *phead,int x)
{
	StackNode* p=(StackNode*)malloc(sizeof(StackNode));
	p->data=x;
	p->next=NULL;
	
	if(phead==NULL)
	{
		phead=p;
		
	}
	else
	{
		p->next=phead;
		phead=p; 
	}

	
	return phead;
}

        (3)链栈-出栈

        出栈,即用一个变量接收出栈的值,随后再定义一个临时指针,指向需要出的结点,用来最后释放掉,之后移动头指针,更新头指针为第二个结点地址,最后释放掉出栈结点即可。

代码如下:

//出栈
StackNode* StackNodepop(StackNode* phead,int x)
{	//单链表可能为空,所以需要先判断非法情况 
	if(phead==NULL)
	return NULL;
	//取第一结点的值 
	x=phead->data;
	//另外赋值第一个结点 ,为了后面找到它并释放 
	StackNode *p=phead;
	//直接更新头节点 
	phead=p->next;
	free(p);
	return phead;
} 

        (4)链栈-打印栈

void StackPrint(StackNode* phead)
{
	StackNode* pos =phead;
	while(pos!=NULL)
	{
		printf("%d->",pos->data);
		pos = pos->next;
	}
	printf("NULL\n");
 } 

总代码如下:(可运行)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//顺序栈
#define MaxSize 50
typedef struct
{
	int data[MaxSize];
	int top;	
}SqStack;
//初始化
void InitStack(SqStack *s)
{
	s->top=-1;
} 
//判断是否栈空
int StackEmpty(SqStack s)
{
	if(s.top== -1)
	return 1;
}
//入栈
void SqPush(SqStack *s,int x)
{
	if(s->top == MaxSize-1)
	{
		exit(-1);//栈满,退出 
	}
	s->top++;
	s->data[s->top]=x;	
} 
//出栈
void Sqpush(SqStack *s,int *n)
{
	if(s->top==-1)
		exit(-1); 
		
	*n=s->data[s->top];
	s->top--;
} 
//栈的链式存储
typedef struct StackNode
{
	int data;
	struct StackNode *next;	
	
}StackNode; 
//入栈
StackNode*  StackNodepush(StackNode *phead,int x)
{
	StackNode* p=(StackNode*)malloc(sizeof(StackNode));
	p->data=x;
	p->next=NULL;
	
	if(phead==NULL)
	{
		phead=p;
		
	}
	else
	{
		p->next=phead;
		phead=p; 
	}

	
	return phead;
}
//出栈
StackNode* StackNodepop(StackNode* phead,int x)
{	//单链表可能为空,所以需要先判断非法情况 
	if(phead==NULL)
	return NULL;
	//取第一结点的值 
	x=phead->data;
	//另外赋值第一个结点 ,为了后面找到它并释放 
	StackNode *p=phead;
	//直接更新头节点 
	phead=p->next;
	free(p);
	return phead;
} 
void StackPrint(StackNode* phead)
{
	StackNode* pos =phead;
	while(pos!=NULL)
	{
		printf("%d->",pos->data);
		pos = pos->next;
	}
	printf("NULL\n");
 } 
int main()
{
	StackNode *phead;
	phead=StackNodepush(phead,0);
	phead=StackNodepush(phead,1);
	phead=StackNodepush(phead,2);
	phead=StackNodepush(phead,3);
	StackPrint(phead);
	
	return 0;
} 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Centos7.6 安装mysql过程全记录

在centos 7.6上 离线安装mysql 的步骤&#xff0c;可参考下文&#xff1a; 一、查看当前MySQL的安装情况并卸载 1. 查看当前MySQL的安装情况 查找之前是否安装了MySQL rpm -qa|grep -i mysql 2.卸载mysql 如果已经安装mysql&#xff0c;则需要先停止MySQL&#xff0c;再删除…

Redis集群 (三十九)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、Redis主从复制 1.1 概念 1.2 作用 1.3 缺点 1.4 流程 1.5 搭建 1.6 验证 二、Reids哨兵模式 2.1 概念 2.2 作用 2.3 缺点 2.4 结构 2.5 搭建 2.6 验证 三、Red…

基于 CentOS 7 构建 LVS-DR 群集 配置nginx负载均衡

环境配置&#xff1a; RHCE客户机192.168.100.146node1lvs192.168.100.145node2RS192.168.100.147node3RS192.168.100.148 配置ipvsadm httpd&#xff1a; [rootnode1 ~]# yum install ipvsadm.x86_64 [rootnode2 ~]# yum install http -y [rootnode2 ~]# systemctl …

SpringBoot案例-部门管理-修改

目录 前言 查看页面原型&#xff0c;明确需求 页面原型 需求 阅读接口文件 思路分析 功能接口开发 控制层&#xff08;Controller类&#xff09; 业务层&#xff08;Service类&#xff09; 业务类 业务实现类 持久层&#xff08;Mapper类&#xff09; 接口测试 前…

centos 7.x 单用户模式

最近碰到 centos 7.9 一些参数设置错误无法启动系统的情况&#xff0c;研究后可以使用单用户模式进入系统进行恢复操作。 进入启动界面&#xff0c;按 e ro 替换为 rw init/sysroot/bin/sh 替换前 替换后 Ctrl-x 进行重启进入单用户模式 执行 chroot /sysroot 可以查看日…

js jquery写一个画板 实现撤回、清空、换色的功能

画布的canvas画板的大小就是这个画板图片的大小 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><metaname"viewport&qu…

云计算|OpenStack|使用VMware安装华为云的R006版CNA和VRM---初步使用(二)

前言&#xff1a; 在前面一篇文章云计算|OpenStack|使用VMware安装华为云的R006版CNA和VRM---初始安装&#xff08;一&#xff09;_华为cna_晚风_END的博客-CSDN博客 介绍了基于VMware虚拟机里嵌套部署华为云的云计算&#xff0c;不过仅仅是做到了在VRM的web界面添加计算节点…

云安全攻防(八)之 Docker Remote API 未授权访问逃逸

Docker Remote API 未授权访问逃逸 基础知识 Docker Remote API 是一个取代远程命令行界面&#xff08;rcli&#xff09;的REST API&#xff0c;其默认绑定2375端口&#xff0c;如管理员对其配置不当可导致未授权访问漏洞。攻击者利用 docker client 或者 http 直接请求就可以…

Spring Boot集成Mybatis Plus通过Pagehelper实现分页查询

文章目录 0 简要说明Pagehelper1 搭建环境1.1 项目目录1.2 项目搭建需要的依赖1.3 配置分页插件拦截器1.4 源代码启动类实体类数据层xml映射文件业务层业务层实现类控制层接口配置swagger请求体 2 可能出现的疑问或者问题2.1 关于total属性疑问2.2 分页不生效问题 3 案例说明3.…

数据库技术--数据库引擎,数据访问接口及其关系详解(附加形象的比喻)

目录 背景数据库引擎Jet数据库&#xff1a;ISAM&#xff1a;ODBC&#xff08;Open Database Connectivity&#xff09;&#xff1a; 数据访问接口ADO&#xff08;ActiveX Data Objects&#xff09;DAO&#xff08;Data Access Objects&#xff09;RDO&#xff08;Remote Data O…

【C语言】操作符详解

目录 一、算数操作符 二、移位操作符 1.左移操作符 2.右移操作符 (1) 逻辑右移 (2) 算术右移 (3)小总结 三、位操作符 四、赋值操作符 五、单目操作符 六、关系操作符 七、逻辑操作符 八、 条件操作符 九、逗号表达式 十、下标引用、函数调用和结构成员 1. [ ]下…

第一百二十八天学习记录:数据结构与算法基础:栈和队列(上)(王卓教学视频)

栈和队列的定义和特点 1、栈和队列是两种常用的、重要的数据结构 2、栈和队列是限定插入和删除只能在表的“端点”进行的线性表 线性表可以在任意一个位置插入和删除&#xff0c;栈只能在最后位置插入和删除 队列 只能删除第一个元素 栈和队列是线性表的子集&#xf…

LeetCode面向运气之Javascript—第27题-移除元素-98.93%

LeetCode第27题-移除元素 题目要求 一个数组nums和一个值val&#xff0c;你需要原地移除所有数值等于val的元素&#xff0c;并返回移除后数组的新长度 举例 输入&#xff1a;nums [3,2,2,3], val 3 输出&#xff1a;2, nums [2,2] 输入&#xff1a;nums [0,1,2,2,3,0,4,2…

Mac思维导图软件Xmind for Mac中文激活版

好的思维导图软件能帮助用户更好的发挥创作能力&#xff0c;XMind是一款流行的思维导图软件&#xff0c;可以帮助用户创建各种类型的思维导图和概念图。 多样化的导图类型&#xff1a;XMind提供了多种类型的导图&#xff0c;如鱼骨图、树形图、机构图等&#xff0c;可以满足不同…

Unity ML-Agent

介绍: 环境搭建 待为完序

温室花卉种植系统springboot框架jsp鲜花养殖智能管理java源代码

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 基于Git无线传感网络的温室花卉种植智能控制系统 系统…

【linux-keepalive】keepalive避免单点故障,高可用配置

keepalive: [rootproxy ~]# yum install -y keepalived [rootproxy ~]# vim /etc/keepalived/keepalived.conf global_defs {router_id proxy1 //设置路由ID号vrrp_iptables //不添加任何防火墙规则 } vrrp_instance V…

C++_模板初阶

在面向对象中&#xff0c;我们可以使用重载来实现多态。 但是问题在于&#xff0c;重载的函数仅仅是类型不同&#xff0c;代码复用率比较低&#xff0c;只要有新的类型出现时&#xff0c;就要增加对应的函数&#xff1b;另一方面它的代码可维护性比较低&#xff0c;一个出错可…

Android之消除APP图标的白色边框

有问题的效果&#xff1a; 解决方案&#xff1a; 第一步&#xff1a;app右键—>new—>Image Asset 第二步&#xff1a;上传Logo图标&#xff0c;选择每种分辨率&#xff0c;预览看效果&#xff0c;选择Resize&#xff0c;可以微调 第三步&#xff1a;点击 Next&#xff…

nbcio-boot升级到3.1后出现online表单新增报错

nbcio-boot升级springboot、mybatis-plus和JSQLParser后出现新增online表单的时候报错&#xff0c;如下&#xff1a; 2023-08-13 21:18:01.292 [http-nio-8080-exec-12] [1;31mERROR[0;39m [36mo.jeecg.common.exception.JeecgBootExceptionHandler:69[0;39m - Handler dispat…