栈的定义及基本操作

news2024/11/15 17:37:56

栈的定义和特点


      栈是一个特殊的线性表,是限定在一端进行插入和删除操作的线性表
      插入到栈顶称作入栈(PUSH) 
      从栈顶删除最后一个元素称作出栈 (POP)

图1 栈的表示

假设三个元素a,b,c入栈顺序为a,b,c,那么出栈顺序有几种?

                                   一般表示一个栈都是竖着列表表示

                                                           栈顶

          c
 b
          a
                                                            栈底

       
cba

表尾                                                                               表头

出栈可以等a,b,c都存放进去在依次出栈,出栈结果为:

a
b
c

也可以放完a,然后a出栈,b和c都入栈后再依次出栈,结果为:

b
c
a

当然也可以a,b先入栈,然后依次出栈,最后c入栈,结果为:

c
a
b

还有几种情况,就不一一举例了

那么会出现b,c,a的情况吗?显然是不可能的,因为栈的特点就是只能在栈顶进行入栈和出栈操作,以上这个例子可以很好反应栈的这个特点。


顺序栈的表示和实现

与链表相同栈的存储方式也分为两种:顺序存储结构和链式存储结构


顺序栈的特点:简单,方便,但容易溢出
顺序栈的存储方式:同一般线性表的顺序存储结构完全相同

用一组连续的存储单元依次顺序放置,从栈底到栈顶的数据元素,栈底一般存放在低地址端

几个重要概念:
//栈满:top-base==stacksize;
/*栈满处理方法:
      报错返回系统
      分配更大的存储空间*/
//空栈:base=top 
      
//上溢:栈已满,又要压入元素 (通常是一种错误)
//下溢:栈已空,又要弹出元素 (通常被用作结束条件) 

 

顺序栈的表示

base表示指向栈底的指针

top表示指向栈顶的指针

//顺序栈的表示
#define MAXSIZE 100;
typedef struct{
	SElemType *base;        //栈底 
	SElemType *top;         //栈顶
	int stacksize;          //最大容量 
}SqStack; 

 

 顺序栈的初始化

相当于建立一个空栈即top=base,两个指针指向相同

//顺序栈的初始化
Status InitStack(SqStack S){
	S.base=(SElemType *)malloc(sizeof(SElemType)*MAXSIZE);//分配存储空间
	if(!S.base){
		printf("OVERLOW");
	} 
	else{
		S.top=S.base;                            //顶指针和底指针指向相同,相当于建立一个空栈 
		S.stacksize=MAXSIZE;
		return OK;
	}
} 

 

判断顺序栈是否为空

空栈的标志性条件top=base,两个指针有相同的指向

如果是空栈返回TURE,如果不是空栈返回FALSE

//判断顺序栈是否为空
Status StackEmpty(SqStack S){
	if(S.top==S.base){                  //判断栈为空的标志base=top; 
		teturn TURE;
	}
	else{
		return FALSE;
	}
} 

 

求顺序栈的长度

这里直接用两个指针相减即可

//求顺序栈的长度
int StackLength(SqStack S){
	return S.top-S.base;         //两个指针相减可以算出中间隔了多少个数据元素,也就是栈的长度 
} 

 

清空顺序栈

这里与清空单链表类似

//清空顺序栈
/*与链表相同,就是把该表置空,但保留表的头结点,栈里的top指针就相当于链表里的头结点*/ 
Status ClearStack(SqStack S){
	if(S.base){
		S.base=S.top;                  //相当与把当前栈变成一个空栈 
	}
} 

看一下单链表的清空


/*清空单链表*/
Status ClearList(LinkList &L){
	Lnode *p,*q;
	p=L->next;                       //p指向首元结点 
	while(p){
		q=p->next;                   //q指向p后面的结点 
		free(p);                     //释放p 
		p=q;                         //p,q指向同一结点 
	}
	L->next=NULL;
	return OK;
}

 销毁顺序栈

与销毁单链表类似

//销毁顺序栈
Status DestoryStack(SqStack S){
	if(S.base){
		S.stacksize=0;                //表长为空 
		S.base=S.top=NULL;            //指针为空 
	}
	return OK; 
}

 销毁单链表

/*销毁单链表(头结点,头指针都不存在)*/
Status DestoryList_L(LinkList &L){     //L为指向头结点的指针 
	Lnode * p;                         //或者LinkList p;
	while(L){                          
		p=L;                           //p和L指向同一个结点 
		L=L->next;                     //L向后移动一个 
		free(p);                       //释放p 
	} 
	return OK;
} 

顺序栈的入栈(注意:栈只能在栈顶进行入栈和出栈操作)

具体步骤
/*判断是否栈满
  将元素e压入栈顶
  栈顶指针加一*/

这里注意栈满的条件:S.top-S.base==stacksize

//顺序栈的入栈
/*判断是否栈满
  将元素e压入栈顶
  栈顶指针加一*/
Status Push(SqStack S,SElemType e){
	if(S.top-S.base==stacksize){         //这里的top指针指向的是栈顶元素的下一个位置 
		return ERROR;                    //栈满 
	}              
	*S.top++=e;
	return OK; 
}  

*S.top++=e;

这一句其实是先将数据元素e放入栈中,然后栈顶指针top移向下一个位置。

如果top指针指向当前表的最后一个数据元素(也就是栈顶元素),即表尾,那么要先将top指针向后移动一位,然后再进行赋值,该语句就变为*++S.top=e;

顺序栈的出栈(注意:栈只能在栈顶进行入栈和出栈操作)

具体步骤
/*判断是否栈空
  获取栈顶元素e
  栈顶指针减一*/

这里的top指针同样也是指向栈顶元素的下一个位置

//顺序栈的出栈
/*判断是否栈空
  获取栈顶元素e
  栈顶指针减一*/
Status Pop(SqStack S,SElemType e){
	if(S.top==S.base){
		return ERROR;
	}
	e=*--S.top;
} 

e=*--S.top;

这一句是先将top指针向下移动一个位置,然后将该位置的数据元素(也就是栈顶元素)赋值给e,

就可以完成出栈。

如果top指针指向当前表的最后一个数据元素(也就是栈顶元素),即表尾,那么就可以先直接将S.top赋值给e,然后将top指针向下移动一个位置,即e=*S.top--;


链栈的表示和实现


链栈是运算受限的单链表,只能在表头进行插入删除操作

与单链表相比较链栈的插入和删除操作就很简单了,相当于只表头进行

图2 链栈的表示



链栈与链表的比较
/*链表的头结点就是栈顶指针top
  链栈里不需要头结点
  链栈基本不存在栈满情况
  空栈相当于头指针指向为空
  插入和删除操作仅存在于栈顶*/

链栈的表示

与单链表的表示很像

//链栈的表示
typedef struct StackNode{
	SElemType data;
	struct StackNode *next;
}StackNode,*LinkStack; 

 

链栈的初始化

相当于建立空栈

 //链栈的初始化
void InitStack(LinkStack S){
	S=NULL;                           //相当与头结点 
	return OK;
}


判断链栈是否为空

如果是空栈返回TURE,如果不是空栈返回FALSE

//判断链栈是否为空
Status StackEmpty(LinkStack S){
	if(S==NULL){
		return TRUE;
	}
	else{
		return FALSE;
	}
} 

链栈的入栈

相当于在S的前面插入新的数据元素,新的数据元素成为栈顶元素

新的数据元素的next域指向S

//链栈的入栈
Status Push(LinkStack S,SElemType e){              //S指向栈顶元素 
	p=(StackNode *)malloc(sizeof(StackNode));      //分配存储空间
	p->data=e;
	p->next=S;
	S=p;
	return OK;
} 

 

链栈的出栈

出栈只需要先保存top指针的内容,然后向下移动一个位置即可

//链栈的出栈
Status Pop(LinkStack S,SElemType e){
	if(S==NULL){
		return ERROR;                  //与顺序栈一样要先判断栈是否为空 
	}
	else{
		e=S->data;
		p=S;
		S=S->next;
		free(p);
		return OK;
	}
} 


取出栈顶元素

直接保存top指针的内容即可

//取出栈顶元素
SElemType GetTop(LinkStack S){
	if(S!=NULL){
		return S->data;
	}
}

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

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

相关文章

【洛谷/水滴题解】[NOIP2005 普及组] 采药

1.难度&#xff1a;普及- 2.类型&#xff1a;dp&#xff0c;01背包 3.描述&#xff0c;输入输出格式&#xff0c;样例&#xff1a; 4.AC代码&#xff1a; #include<bits/stdc.h> using namespace std; int t,m; int dp[1005]; int main() {ios::sync_with_stdio(false…

MySQL第8讲--DCL(数据控制语言)的基本操作

文章目录 前言DCL(数据控制语言)用户管理查询用户创建用户修改用户密码删除用户 权限控制查询权限授予权限撤销权限 前言 在第六讲MySQL第6讲–DQL(数据查询语言)的基本操作之基本和条件查询和第七讲MySQL第7讲–DQL(数据查询语言)的基本操作中我们讲述了DQL中的&#xff0c;基…

高性能云桌面在工业设计中的应用,百度智能云云桌面给出答案

在之前的文章中我们讲到&#xff0c;边缘云桌面可以通过在距离用户较近的边缘节点上直接处理数据和应用&#xff0c;减少了数据传输时间&#xff0c;降低延迟&#xff0c;提高数据处理的速度和安全性。用户可以通过任何设备&#xff0c;随时随地访问自己的桌面环境&#xff0c;…

每日OJ_牛客HJ59 找出字符串中第一个只出现一次的字符

目录 牛客HJ59 找出字符串中第一个只出现一次的字符 解析代码 牛客HJ59 找出字符串中第一个只出现一次的字符 找出字符串中第一个只出现一次的字符_牛客题霸_牛客网 解析代码 可以用一个数组的每一个位置表示对应的位置。对应的字符位置存放字符出现的次数。统计完之后&…

【云备份】学习bundle库

文章目录 1.认识bundle⽂件压缩库bundle库实现⽂件压缩bundle实现文件解压缩 1.认识bundle⽂件压缩库 BundleBundle 是一个嵌入式压缩库&#xff0c;支持23种压缩算法和2种存档格式。使用的时候只需要加入两个文件 bundle.h 和 bundle.cpp 即可。 showcase #include <cass…

安全入门day.02

一、环境部署 1、windows版本 2、Linux版本 二、WEB应用组成角色名词 1、开发语言 2、程序源码 3、中间件容器 4、数据库 5、服务器操作系统 6、第三方软件 三、WEB应用安全漏洞分类 1、SQL注入 2、文件安全 3、RCE执行 4、XSS跨站 5、CSRF/SSRF/CRLF 6、反序列…

基于RK3568 Android11 移除长按电源按键弹窗的对话框中的 [关机] 和 [紧急呼救] 选项(详细分析)

一般来说&#xff0c;与Android按键窗口事件相关的基本是与frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java 这个文件有关。   因此先打开与输入相关的日志&#xff0c;如下&#xff1a;   然后重新编译烧录后查看打印的日志可以看…

Matcha-Tts:一种基于条件流匹配的快速Tts架构笔记

MATCHA-TTS: A FAST TTS ARCHITECTURE WITH CONDITIONAL FLOW MATCHING笔记 提出问题&#xff1a; 1、合成速度慢 提出方法&#xff1a; 首先&#xff0c;提出了一种改进的编码器-解码器TTS架构&#xff0c;在解码器中使用1D CNN和Transformer的组合。这样减少了内存消耗&am…

使用tailwindcss轻松实现移动端rem适配

本示例节选自小卷全栈开发实战系列的《Vue3实战》。演示如何用tailwindcss所支持的rem体系轻松实现一个仿b站移动端头部导航栏rem适配。 友情声明 学习分享不易&#xff0c;如果小伙伴觉得有帮助&#xff0c;点赞支持下。满30赞&#xff0c;将随文附赠录屏讲解&#xff0c;感谢…

linux shell 脚本入门到实战

目录 一、shell入门简介1.1什么是shell1.2shell编程注意事项1.3第一个shell脚本helloworld 二、shell环境变量讲解2.1shell变量详解2.2shell系统变量介绍2.3shell环境变量介绍2.4shell用户环境变量介绍2.4.1自定义shell环境变量 三、shell编程流程控制语句3.1if条件语句介绍3.1…

TikTok出现“无网络连接”,具体原因与解决方法

“No network connection”&#xff01;当你信心满满下载并准备开始运营TikTok时&#xff0c;屏幕上如果提示“无互联网连接”非常难办。有很多因素可能会导致此问题&#xff0c;包括网络连接无效、应用程序故障等。接下来将为你盘点主要的原因与解决方法。 一、无网络连接的原…

C语言进阶(9)

程序的执行时有两种环境&#xff0c;一种是翻译环境&#xff0c;另一种是执行环境。程序先经过编译成为obj的后缀的文件&#xff0c;然后将文件和链接库链接起来&#xff0c;然后将形成可执行程序&#xff0c;前者时翻译环境&#xff0c;后者时执行环境。(链接库就是库函数的所…

【ComfyUI】Error occurred when executing WD14Tagger|pysssss :

解决ComfyUI的ComfyUI-WD14-Tagger插件运行报错问题 参考ONNX 运行时的 CUDA 和 cuDNN 加载错误 期刊 #56 pythongosssss/ComfyUI-WD14-标记器 (github.com) 我尝试了以下操作 转到 启动器&#xff0c; 启动CMD&#xff0c; 按回车键&#xff1a; 粘贴。卸载两个包 pip unin…

Linux之进程间通信(下)

目录 命名管道 命名管道的创建 匿名管道和命名管道的区别 命名管道的代码实现 共享内存 创建共享内存 关联共享内存 去关联共享内存 删除共享内存 共享内存特点 共享内存代码实现 IPC资源总结 命名管道 上期我们学习了匿名管道&#xff0c;匿名管道本质就是一个…

EcoVadis评估对可持续发展具体表现在哪些方面

Ecovadis认证是一项备受推崇的环保和社会责任认证&#xff0c;其优势不仅在于其权威性和公信力&#xff0c;更在于其全面而深入的评估标准&#xff0c;这个认证体系将企业划分为不同的等级&#xff0c;从入门级的银牌到最高级别的白金级&#xff0c;每个等级都有相应的评估标准…

Selenium + Python 自动化测试14(发送报告)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了使用HTMLTestRunner 生成HTML报告的方法。 本篇文章我们接着讲生成HTML报告是否可以自动邮件发送出去&#xff0c;提高我们测试报告的及时性&#xff0c;方便…

PCB入门笔记—绘制一个只有两个排针的PCB全流程记录—立创EDA专业版

PCB绘制入门&#x1f680; 硕士毕业之后准备进入博士阶段&#xff0c;本科阶段做的硬件&#xff0c;硕士阶段做的算法&#xff0c;然后博士阶段又要做回硬件了&#xff0c;因此也是打算补一补PCB相关的内容和知识&#xff0c;毕竟做控制的话&#xff0c;之后这也是不能躲开的必…

前端工程化-02.Yapi接口管理平台

YApi Pro-高效、易用、功能强大的可视化接口管理平台 图片中链接已失效&#xff0c;此处为新链接 选择添加接口&#xff0c;输入接口名称和接口路径。 创建成功后自动进入接口页面&#xff0c;点击编辑&#xff0c;可以编辑完善这个接口的信息。两个非常重要的信息&#xff1a…

进程waitwaitpid、线程

一、wait wait功能 1、获取子进程退出状态&#xff0c;分析子进程是否已经退出&#xff08;变成僵尸态&#xff09; 2、回收资源&#xff0c;让僵尸态子进程销毁 wait本身是一个阻塞操作&#xff0c;会使调用者阻塞 2、宏&#xff1a; &#xff08;1&#xff09;WIFEXITE…

bug的常见排查和分析思路以及相关的原因分类

作为开发人员&#xff0c;经常会收到来自用户和QA&#xff0c;领导反馈的各种问题。 为了快速问题&#xff0c;我们有时需要站在更高的角度&#xff0c;更全面的看待问题。才能更快锁定问题。 具体的bug还需要结合企业实际业务情况&#xff0c;相关的框架&#xff0c;依赖库&…