【数据结构】三、栈和队列: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.rhkb.cn/news/316866.html

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

相关文章

nodejs写接口(一)

一、新手上路十大步 &#xff08;1&#xff09;先建一个常用的文件夹 &#xff08;2&#xff09;使用code打开 &#xff08;3&#xff09;在里面新建一个index.js文件 &#xff08;4&#xff09;新建项目 npm init -y //用于自己搭建一个项目框架&#xff08;写框架&#xf…

代码审计之SAST自动化

前言: 很久没写文章了&#xff0c;有点忙&#xff0c;落个笔&#xff0c;分享一些捣鼓或说适配好的一些好玩的东西。 脚本工具不开源&#xff0c;给一些思路&#xff0c;希望能给大家带来一些收获。 笔者能力有限&#xff0c;如有错误&#xff0c;欢迎斧正。 正文&#xff1a…

《软件设计师教程:计算机网络浅了解计算机之间相互运运作的模式》

​ 个人主页&#xff1a;李仙桎 &#x1f525; 个人专栏: 《软件设计师》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ​ ⛺️前言&#xff1a;各位铁汁们好啊&#xff01;&#xff01;&#xff01;&#xff0c;今天开始继续学习中级软件设计师考试相关的内容&#xff0…

3节点ubuntu24.04服务器docker-compose方式部署高可用elk+kafka日志系统并接入nginx日志

一&#xff1a;系统版本: 二&#xff1a;部署环境&#xff1a; 节点名称 IP 部署组件及版本 配置文件路径 机器CPU 机器内存 机器存储 Log-001 10.10.100.1 zookeeper:3.4.13 kafka:2.8.1 elasticsearch:7.7.0 logstash:7.7.0 kibana:7.7.0 zookeeper:/data/zookeep…

数字电子:二进制逻辑和信号

目录 模拟值 数字值 真和假 下拉电阻和上拉电阻 模拟值 模拟值是随时间连续变化的量。它可以取无限多的值——例如&#xff0c;温度、电池电压或扬声器中的音频信号。图1显示了模拟值的时间过程。模拟的概念可以通过连续性条件来表示。在实践中&#xff0c;数值沿着一个以…

代码随想录算法训练营DAY32|C++贪心算法Part.2|122.买卖股票的最佳时机II、55.跳跃游戏、45.跳跃游戏II

文章目录 122.买卖股票的最佳时机II思路CPP代码 55.跳跃游戏思路CPP代码 45.跳跃游戏II思路方法一代码改善 CPP代码 122.买卖股票的最佳时机II 力扣题目链接 文章讲解&#xff1a;122.买卖股票的最佳时机II 视频讲解&#xff1a; 状态&#xff1a;本题可以用动态规划&#xff0…

企业智能名片小程序:AI智能跟进功能助力精准营销新篇章

在数字化浪潮的推动下&#xff0c;企业营销手段不断迭代升级。如今&#xff0c;一款集手机号授权自动获取、智能提醒、访客AI智能跟进及客户画像与行为记录于一体的企业智能名片小程序&#xff0c;正以其强大的AI智能跟进功能&#xff0c;助力企业开启精准营销的新篇章。 通过深…

小程序 rich-text 解析富文本 图片过大时如何自适应?

在微信小程序中&#xff0c;用rich-text 解析后端返回的数据&#xff0c;当图片尺寸太大时&#xff0c;会溢出屏幕&#xff0c;导致横向出现滚动 查看富文本代码 图片是用 <img 标签&#xff0c;所以写个正则匹配一下图片标签&#xff0c;手动加上样式即可 // content 为后…

​HTTP与HTTPS:网络通信的安全卫士

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起进步&am…

C语言.自定义类型:结构体

自定义类型&#xff1a;结构体 1.结构体类型的声明1.1结构体回顾1.1.1结构体的声明1.1.2结构体变量的创建和初始化 1.2结构体的特殊声明1.3结构体的自引用 2.结构体内存对齐2.1对齐规则2.2为什么存在内存对齐2.3修改默认对齐数 3.结构体传参4.结构体实现位段4.1什么是位段4.2位…

配置jupyter的启动路径

jupyter的安装参考&#xff1a;python环境安装jupyter-CSDN博客 1&#xff0c;背景 继上一篇python环境安装jupyter&#xff0c;里面有一个问题&#xff0c;就是启动jupyter&#xff08;命令jupyter notebook&#xff09;之后&#xff0c;页面默认显示的是启动时候的路径。 …

实验15 MVC

二、实验项目内容&#xff08;实验题目&#xff09; 编写代码&#xff0c;掌握MVC的用法。 三、源代码以及执行结果截图&#xff1a; inputMenu.jsp&#xff1a; <% page contentType"text/html" %> <% page pageEncoding "utf-8" %> &…

WSL2无法ping通本地主机ip的解决办法

刚装完WSL2的Ubuntu子系统时&#xff0c;可能无法ping通本地主机的ip&#xff1a; WSL2系统ip&#xff1a; 本地主机ip&#xff1a; 在powershell里输入如下的命令&#xff1a; New-NetFirewallRule -DisplayName "WSL" -Direction Inbound -InterfaceAlias &quo…

linux 搭建知识库文档系统 mm-wiki

目录 一、前言 二、常用的知识库文档工具 2.1 PingCode 2.2 语雀 2.3 Tettra 2.4 Zoho Wiki 2.5 Helpjuice 2.6 SlimWiki 2.7 Document360 2.8 MM-Wiki 2.9 其他工具补充 三、MM-Wiki 介绍 3.1 什么是MM-Wiki 3.2 MM-Wiki 特点 四、搭建MM-Wiki前置准备 4.1 前置…

华为配置mDNS网关示例(AP与AC间二层转发)

华为配置mDNS网关示例&#xff08;AP与AC间二层转发&#xff09; 组网图形 图1 配置mDNS网关组网图 组网需求配置思路操作步骤配置文件 组网需求 如图1所示&#xff0c;某企业的移动终端通过WLAN连接网络&#xff0c;AP_1和AP_2分别与AC之间采用二层转发。部门1和部门2分别属…

利用大型语言模型提升个性化推荐的异构知识融合方法

在推荐系统中&#xff0c;分析和挖掘用户行为是至关重要的&#xff0c;尤其是在美团外卖这样的平台上&#xff0c;用户行为表现出多样性&#xff0c;包括不同的行为主体&#xff08;如商家和产品&#xff09;、内容&#xff08;如曝光、点击和订单&#xff09;和场景&#xff0…

场景文本检测识别学习 day06(Vi-Transformer论文精读)

Vi-Transformer论文精读 在NLP领域&#xff0c;基于注意力的Transformer模型使用的非常广泛&#xff0c;但是在计算机视觉领域&#xff0c;注意力更多是和CNN一起使用&#xff0c;或者是单纯将CNN的卷积替换成注意力&#xff0c;但是整体的CNN 架构没有发生改变VIT说明&#x…

IP定位技术企业网络安全检测

随着信息技术的飞速发展&#xff0c;网络安全问题日益凸显&#xff0c;成为企业运营中不可忽视的一环。在众多网络安全技术中&#xff0c;IP定位技术以其独特的优势&#xff0c;为企业网络安全检测提供了强有力的支持。本文将深入探讨IP定位技术在企业网络安全检测中的应用及其…

微信小程序webview和小程序通讯

1.背景介绍 1.1需要在小程序嵌入vr页面&#xff0c;同时在vr页面添加操作按钮与小程序进行通信交互 1.2 开发工具&#xff1a;uniapp开发小程序 1.3原型图 功能&#xff1a;.点击体验官带看跳转小程序的体验官带看页面 功能&#xff1a;点击立即咨询唤起小程序弹窗打电话 2.…

从车规传感器发展的正反面,看智驾发展的“胜负手”

北京车展进程过半&#xff0c;雷军和周鸿祎成为车展新晋“网红”的同时&#xff0c;智能驾驶成为观众讨论最务实的话题之一。端到端自动驾驶、城市NOA这些炙手可热的话题&#xff0c;占据了大部分的关注度。 但在高阶智能驾驶之外&#xff0c;智能驾驶同样具有频繁使用需求的低…