【数据结构】三、栈和队列:2.顺序栈共享栈(顺序栈的初始化,判空,进栈,出栈,读取栈顶,顺序栈实例)

文章目录

    • 1.顺序栈
      • 1.1初始化
      • 1.2判空
      • 1.3进栈
      • 1.4出栈
      • 1.5读取栈顶
      • 1.6销毁栈
      • ❗1.7顺序栈c++实例
    • 2.共享栈
      • 2.1初始化
      • 2.2判满

1.顺序栈

顺序存储实现的栈

顺序栈的缺点:栈的大小不可变。

#define MaxSize 10			//定义栈中元素的最大个数
typedef struct{ElemType data[MaxSize];	//静态数组存放栈中元素int top;				//栈顶指针
} SqStack;				//Sq即sequence:顺序的意思

有的顺序栈结构还有栈的大小stackSize

typedef struct{ElemType* base;	//栈底指针:base指针不动、top往上移ElemType* top;	//栈顶指针int stackSize;	//当前已分配的存储空间大小,即顺序栈的大小
} SqStack;			//顺序栈的结构体定义

顺序存储:给各个数据元素分配连续的存储空间,大小为 MaxSize * sizeof(ElemType)。

1.1初始化

InitStack(&S):初始化栈。构造一个空栈S,分配内存空间。

#define MaxSize 10			//定义栈中元素的最大个数
typedef struct {ElemType data[MaxSize];	//静态数组存放栈中元素int top;				//栈顶指针
} SqStack;//初始化
void InitStack(SqStack &S) {S.top = -1;				//初始化栈顶指针
}void main() {SqStack S; 				//声明一个顺序栈(分配空间)InitStack(S);//后续操作...
}

初始化有两种方式:

栈顶指针top指向栈顶元素,一般存储的是数组的下标。(一般初始化时top=-1)

  1. 初始化时top=-1,那么元素从0开始。top当前指向的位置就是栈顶。

    如果有abcde,5个元素,那么满栈top=4。

    • 入栈:S.data[++S.top]=x;
    • 出栈:x=S.data[S.top-];
    • 获得栈顶元素:x=S.data[S.top];
  2. 初始化时top=0。top当前指向的位置是栈顶上面的一个没有元素的空位置。

    • 入栈:S.data[S.top++]=x;
    • 出栈:x=S.data[–S.top];
    • 获得栈顶元素:x=S.data[S.top-1];

1.2判空

StackEmpty(S):断一个栈S是否为。若S为空,则返回true,否则返回false。

时间复杂度:O(1)

//判断栈空
bool StackEmpty(SqStack S) {if(S.top == -1)	//栈空return true;else			//不空return false;
}

1.3进栈

Push(&S,x):插入,进栈。若栈S未满,则将x加入使之成为新栈顶

时间复杂度:O(1)

//新元素入栈
bool Push(SqStack &S, ElemType x) {if (S.top == MaxSize-1)	//栈满,报错return false;S.top = S.top+1;		//指针先加1S.data[S.top] = x;		//新元素入栈return true;
}

上述代码中,指针+1,然后新元素入栈的两段代码可以等价于:

S.data[++S.top] = x;

注意是++S.top先加再用,而不是S.top++先用再加。

1.4出栈

Pop(&S,&x):删除,出栈。若栈S非空,则弹出栈顶元素,并用x返回。

时间复杂度:O(1)

//出栈操作
bool Pop(SqStack &S, ElemType &x) {if(S.top == -1)		//栈空,报错return false;x = S.data[S.top];	//栈顶元素先出栈S.top = S.top-1;	//指针再减1return true;
}

注意:这里top-1,数据其实还残留在内存中,只是逻辑上被删除了。

上述代码中也可以等价于:

x = S.data[S.top--];

注意是S.top--先用再减,而不是--S.top先减再用。

1.5读取栈顶

GetTop(S,&x):读取栈顶元素。若栈S非空,则用x返回线顶元素。

时间复杂度:O(1)

//读栈顶元素
bool GetTop(SqStack S, ElemType &x) {if(S.top == -1)		//栈空,报错return false;x = S.data[S.top];	//×记录栈顶元素return true;
}

读取栈顶元素和出栈操作十分相似,唯一不同是不需要出栈之后top指针-1。

1.6销毁栈

顺序栈是在声明栈时直接分配内存,并没有使用malloc函数,所以不需要手动free,函数运行结束后系统自动回收空间。

但是如果使用了动态分配那么就需要手动释放空间:

//销毁栈、释放栈的内存
void DestroyStack(SqStack& stack){if(stack.base) {			//若栈底指针分配有地址,则释放delete stack.base;	//释放栈底指针的地址stack.top = -1;			//令栈顶位置为0stack.base = NULL;	//将栈底指针指向空cout << "栈已释放内存!" << endl; }
}

❗1.7顺序栈c++实例

C++是一门面向对象的高级语言,在我们编写代码中,常常离不开对对象的创建和清理对象资源。而兼容过来的mallocfree并不能很好的满足我们的需求,从而C++将mallocfree封装起来并起了新的名字newdelete,这两个关键字的作用不仅比mallocfree的功能强大,用起来也非常的方便。

new和delete都是运算符,不是库函数,不需要单独添加头文件。

格式:

new

  • 类型指针 指针变量名 = new 类型
  • 类型指针 指针变量名 = new 类型(初始值)
  • 类型指针 指针变量名 = new 类型[元素个数]

delete

  • delete 指针变量名
  • delete[] 指针变量名
#include<iostream>
#include<Windows.h>
using namespace std;#define MaxSize 10				//栈最大可以存放的元素个数
typedef int ElemType;		//顺序栈存储的数据类型、用int代替ElemType//创建顺序栈typedef struct
{ElemType* base;  //栈底指针int top;		 //栈顶的位置 如 0、1、2、3、4....MaxSize
} SqStack;			 //顺序栈的结构体定义bool InitStack(SqStack& stack);	//初始化栈
bool StackEmpty(SqStack stack);//判断是否为空
bool StackFull(SqStack stack);	//判断是否已满
int GetStackSize(SqStack& stack);//获取顺序栈中元素个数bool Push(SqStack& stack, ElemType value);//入栈
bool Pop(SqStack& stack, ElemType& value);//出栈
bool GetTop(SqStack& stack, ElemType& value);//获取栈顶的元素
void DestroyStack(SqStack& stack);//销毁栈、释放栈的内存//--------------------------------------------------
void CreatStack(SqStack stack){int number, value = 0;cout << "请输入需要插入的元素个数:";cin >> number;while (number > 0){cin >> value;Push(stack, value);	//放入栈number--;value++;}
}int main()
{SqStack	stack;		//创建顺序栈InitStack(stack);	//初始化顺序栈
//例如插入    int value = 5;      //插入5个元素while (value > 0){Push(stack, value);	//放入栈value--;}//获取栈顶的元素GetTop(stack, value);cout << "当前栈顶的元素是:" << value << endl;//获取栈的元素个数cout << "当前栈的元素个数是:" << GetStackSize(stack) << endl;//出栈cout << "出栈顺序:" << endl;while (!StackEmpty(stack)){Pop(stack, value);cout << value << " "; }cout << endl;//释放栈的内存DestroyStack(stack);system("pause");return 0;
}//-----------------------------------------------------------------------
//初始化顺序栈
bool InitStack(SqStack& stack){//注意:这里使用new进行空间分配,所以在后面摧毁栈的时候需要delete释放空间//动态分配一个ElemType类型MaxSize长度的空间,将地址给顺序栈Stack的栈底指针stack.base = new ElemType[MaxSize];//判断顺序栈的栈底指针(stack.base)是否为空,若无地址,则分配失败if(!stack.base){return false; }stack.top = -1;		//初始化栈顶指针的位置为-1return true;
}//判断栈空
bool StackEmpty(SqStack stack){if (stack.top == -1)return true;elsereturn false; 
}//判断栈满
bool StackFull(SqStack stack){if (stack.top == MaxSize-1)   //top的位置值等于MaxSize-1时栈满,因为是从0开始的return true; elsereturn false; 
}//顺序栈中元素个数
int GetStackSize(SqStack& stack){return stack.top+1;  //栈顶位置即top的数值,就是栈中元素的个数
}/*** @brief 顺序栈入栈:* 开辟一个新的空间,栈顶+1,然后将数据存入stack.base[stack.top]所在的位置.* * @param stack * @param value * @return true * @return false */
bool Push(SqStack& stack, ElemType value){if (StackFull(stack)){cout<<"栈满"<<endl;return false;  }//若栈未满,执行入栈操作stack.top++;		//栈顶自增1stack.base[stack.top] = value;    //以栈顶位置作为下标存储数据return true;
}/*** @brief 顺序栈出栈:* 读取栈顶stack.base[stack.top]的元素,然后使栈顶-1.* * @param stack * @param value * @return true * @return false */
bool Pop(SqStack& stack, ElemType &value){if (StackEmpty(stack)){cout<<"栈为空"<<endl;return false;}value = stack.base[stack.top];	//以栈顶位置作为下标的值赋值给value返回stack.top--;	//栈顶自减1return true;
}//读取栈顶元素
bool GetTop(SqStack& stack, ElemType &value){if (StackEmpty(stack)){cout<<"栈为空"<<endl;return false; }value = stack.base[stack.top];return true; 
}//销毁栈、释放栈的内存
void DestroyStack(SqStack& stack){if(stack.base) {			//若栈底指针分配有地址,则释放delete stack.base;	//释放栈底指针的地址stack.top = -1;			//令栈顶位置为0stack.base = NULL;	//将栈底指针指向空cout<<"栈已释放内存!"<<endl; }
}

当前栈顶的元素是:1
当前栈的元素个数是:5
出栈顺序:
1 2 3 4 5
栈已释放内存!

2.共享栈

因为顺序栈的缺点是栈的大小不可变,所以引出共享栈,两个栈共享一片空间。这片存储空间不单独属于任何一个栈,某个栈需要的多一点,它就可能得到更多的存储空间。两个栈的栈底在这片存储空间的两端,当元素入栈时,两个栈的栈顶指针相向而行。

在这里插入图片描述

2.1初始化

#define MaxSize 10			//定义栈中元素的最大个数
typedef struct {ElemType data [MaxSize];//静态数组存放栈中元素int top0;				//0号栈线顶指针int top1;				//1号栈线顶指针
} ShStack;//初始化栈
void InitStack(ShStack &S) {S.top0 = -1;				//初始化栈顶指针S.top1 = MaxSize;
}

2.2判满

top0从-1开始,top1从MAX开始。那么放入元素后,top0逐渐增大,top1减小。当他们下一个指针的位置在一起时,说明这个栈已经放满元素。

top0+1 == top1

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

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

相关文章

leetcode1143. 最长公共子序列(ACM模式解法)

题目描述 给你一个序列X和另一个序列Z&#xff0c;当Z中的所有元素都在X中存在&#xff0c;并且在X中的下标顺序是严格递增的&#xff0c;那么就把Z叫做X的子序列。 例如&#xff1a;Z是序列X的一个子序列&#xff0c;Z中的元素在X中的下标序列为<1,2,4,6>。 现给你两个…

指纹浏览器:网络安全与隐私的新工具

在互联网时代&#xff0c;隐私和网络安全成为人们越来越关注的话题。随着数字化的发展&#xff0c;个人信息的泄露和在线追踪的问题愈发严峻。在这个背景下&#xff0c;"指纹浏览器"作为一种新型工具&#xff0c;开始受到关注。撸空投需要了解指纹浏览器。本文将深入…

软考-信息系统项目管理师-论文技术架构模板(60天备考第26天)

分享一段信息系统项目管理师论文项目技术架构描述的万能模板&#xff0c;供大家参考。距离考试还有二十八天&#xff0c;如果论文写不好的可以加微进论文指导群学习论文写作。 该系统前端基于Vue开发&#xff0c;后端基于java开发&#xff0c;前后端分离部署。整体采用B/S架构&…

【收藏全开源】JAVA共享自习室共享学习室无人系统支持微信小程序+微信公众号+H5_博纳软云

JAVA打造无人自习室新纪元&#xff1a;微信小程序、公众号与H5三合一共享学习空间 在信息化时代的浪潮下&#xff0c;学习方式正经历着前所未有的变革。JAVA技术以其强大的跨平台性和稳定性&#xff0c;引领着共享自习室领域迈向新的高度。我们推出的无人自习室共享学习室系统…

EVRPD-440NZ5M智能型电压保护器 施耐德韩国三和

EVRPD-440NZ5M智能型电压保护器 施耐德韩国三和 EVR-PD是施耐德EOCR的一款电压保护器产品&#xff0c;具有过电压、欠电压、缺相、逆相、电压不平衡等保护功能 EOCR简介&#xff1a; EOCR即Electronic Over Current Relays电子式电动机保护继电器英文缩写&#xff0c;韩国三…

今年做电商,视频号小店可以冲一下,这次腾讯不负所望站在了风口

腾讯做电商&#xff0c;能不能搞&#xff1f; 对于腾讯做电商这件事&#xff0c;很多玩家并不看好&#xff0c;毕竟腾讯想做的东西太多了&#xff0c;做电商这件事也曾失败过&#xff1b; 但是这次&#xff0c;无论是电商老玩家还是新手玩家&#xff0c;腾讯推出的视频号小店…

C++复盘(一)

文章目录 常量标识符命名规则数据类型sizeof关键字浮点数字符型转义字符字符串型布尔类型bool 比较运算符switch-case语句rand()随机数种子srand() goto语句一维数组函数函数的声明函数的分文件编写 指针指针所占内存空间空指针野指针const修饰指针1、常量指针2、指针常量3、co…

element的el-table 解决表格多页选择数据时,数据被清空

问题&#xff1a;切换页码时&#xff0c;勾选的数据会被清空 重点看我圈出来的&#xff0c;直接复制&#xff0c;注意&#xff0c;我这里 return row.productId;一般大家的是 return row.id,根据接口定的唯一变量 :row-key"getRowKeys"​​​​​​​:reserve-sele…

Android CalendarView助你打造精美的Android日历应用

Android CalendarView助你打造精美的Android日历应用 1. 引言 移动应用中的日历功能对于用户来说至关重要&#xff0c;它不仅是时间管理的工具&#xff0c;还能帮助用户记录重要事件和安排活动。因此&#xff0c;一个高效、易用的日历控件对于移动应用的成功至关重要。 传统…

通过AI助手实现一个nas定时任务更新阿里云域名解析

一.通过AI助手实现一个ip-domain.py的脚本 起一个Python脚本&#xff0c;ip-domain.py&#xff1b;注意已安装Python3.的运行环境&#xff1b;将下面阿里云相关配置添加&#xff0c;注意这里引用了两个包&#xff0c;requests和alibabacloud_alidns20150109&#xff1b;执行前…

一文带你了解5款高效率软件,建议收藏

​ 人类与99%的动物之间最大差别在于是否会运用工具&#xff0c;借助好的工具&#xff0c;能提升几倍的工作效率。 1. 高速文件复制——TeraCopy ​ TeraCopy是一款高效的文件复制工具&#xff0c;可以大幅度提高文件复制和移动的速度。它支持多线程复制、错误恢复、校验和等…

React的路由

1. 什么是前端路由 一个路径 path 对应一个组件 component 当我们在浏览器中访问一个 path 的时候&#xff0c;path 对应的组件会在页面中进行渲染 2. 创建路由开发环境 # 使用CRA创建项目 npm create-react-app react-router-pro# 安装最新的ReactRouter包 npm i react-ro…

罗宾斯《管理学》第13版/教材讲解/考研真题视频课程/网课

本课程是罗宾斯《管理学》&#xff08;第13版&#xff09;精讲班&#xff0c;为了帮助参加研究生招生考试指定考研参考书目为罗宾斯《管理学》&#xff08;第13版&#xff09;的考生复习专业课&#xff0c;我们根据教材和名校考研真题的命题规律精心讲解教材章节内容。 序号名…

前端工程化Vue使用Node.js永久设置国内高速npm镜像源

前端工程化Vue使用Node.js永久设置国内高速npm镜像源 接续上篇错误收录&#xff0c;此篇通过简单配置永久设置国内高速npm镜像源方法 1.更换新版镜像 清空npm缓存 npm cache clean --force修改回原版镜像源或直接删除配置过的镜像源 npm config set registry https://registr…

Linux挂载硬盘

1、查看硬盘数量 fdisk -l # 可以看到三个磁盘 # /dev/vda 50G # /dev/vdb 100G 新增 # /dev/vdc 100G 新增2、查看当前挂载情况 df -h # 可以看到50G的已经挂载3、格式化待挂载盘 # 对新的数据盘进行挂载前要进行格式化&#xff0c;只有格式化后才可以挂载 mkfs.ext4 /dev/…

电商技术揭秘三十五:智能风控功能架构浅析

相关系列文章 电商技术揭秘相关系列文章合集&#xff08;1&#xff09; 电商技术揭秘相关系列文章合集&#xff08;2&#xff09; 电商技术揭秘二十八&#xff1a;安全与合规性保障 电商技术揭秘二十九&#xff1a;电商法律合规浅析 电商技术揭秘三十&#xff1a;知识产权保…

【c++】优先级队列与仿函数:C++编程的强大组合

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本篇文章我们来讲解优先级队列priority_queue 目录 1.priority_queue的介绍和使用函数使用仿函数的使用与介绍greater和less 2.priority_queue的模拟实现基本框架…

统一化数据库:为大语言模型垂域应用奠定基础

编者按&#xff1a;检索增强生成&#xff08;RAG&#xff09;技术因在减少生成幻觉和虚构信息方面的显著效果&#xff0c;以及对知识及时更新能力的改善&#xff0c;正逐渐成为大语言模型系统的主流架构之一。随着 RAG 技术的广泛应用&#xff0c;其核心组件——向量数据库&…

2022 csp-j 答案(精选题)

主题目 16 - 21题 22 - 27题 28 - 34题 35 -39题 40 - 44题 精选题目 答案及解析 28题 答案&#xff1a;T 解析&#xff1a;考查时间复杂度评估。 31题 答案&#xff1a;A 解析&#xff1a;模拟即可。 32题 答案&#xff1a;B 解析&#xff1a;模拟即可。 34题 答…

线上线下包搭建小程序/公众号/H5 支持二开!

网上交友有以下三个积极影响&#xff1a; 1. 扩展社交圈和增加社交机会&#xff1a;网上交友可以让人们接触到不同地区、不同背景、不同文化的人&#xff0c;拓展人们的社交圈并且增加交友机会。这些新的社交联系对于个人的成长和发展有积极的影响&#xff0c;可以让人们学习新…