数据结构与算法-栈

在这里插入图片描述

栈和队列是两种常用的线性结构,属于特殊的线性表,是线性表相关运算的一个子集。一般来说,线性表上的插入和删除操作不受任何限制,但栈只能在表的一端进行插入和删除操作,而队列则只能在一端进行插入操作,在另一端进行删除操作。因此,栈和队列通常称为操作受限的线性表。

  • 🎈1.栈的定义
  • 🎈2.栈的抽象数据类型
  • 🎈3.顺序栈
    • 🔭3.1顺序栈的类定义
    • 🔭3.2初始化建立空栈
    • 🔭3.3入栈操作
    • 🔭3.4退栈操作
    • 🔭3.5栈判空操作
    • 🔭3.6返回栈顶元素
    • 🔭3.7打印栈
    • 🔭3.8全部代码
  • 🎈4.链栈
    • 🔭4.1链栈的类定义
    • 🔭4.2创建空栈
    • 🔭4.3销毁栈
    • 🔭4.4入栈操作
    • 🔭4.5退栈操作
    • 🔭4.6判空操作
    • 🔭4.7返回栈顶元素
    • 🔭4.8打印栈
    • 🔭4.9全部代码

🎈1.栈的定义

栈是限定在表的一端进行插入和删除操作的线性表。表中允许插入和删除操作的一端称为栈顶,另一端叫做栈底。当栈中没有任何元素时称为空栈。栈顶位置是动态的,由一个栈顶的指针(top)指示其位置(具体实现时一般指向当前元素的下一个空位)。栈的插入操作通常称为压栈或进栈,删除操作通常称为退栈或出栈。栈具有“后进先出,先进后出”的特点,即后进栈的元素先出栈。
栈操作示例图:
在这里插入图片描述

🔎假设这里有三个元素a、b、c,如果进栈顺序是abc,那么出栈的顺序有几种可能呢?
5种:abc acb cba bac bca

🎈2.栈的抽象数据类型

在这里插入图片描述

🎈3.顺序栈

顺序栈是指用一组地址连续的存储空间依次存放栈中元素的存储结构,并用一个变量top指向当前栈顶元素的下一个空位来反映栈中元素的变化情况,另一个变量base指向栈底。顺序栈的存储结构如下图所示:
在这里插入图片描述

🔭3.1顺序栈的类定义

#define InitStackSize 100
#define StackIncrement 10
typedef int SElemType;
class Sqstack
{
private:SElemType* base;//栈底指针,SElemType为栈中元素类型SElemType* top;//栈顶指针int stacksize;//栈容量
public:Sqstack();//构造函数,初始化建立一空栈~Sqstack()//析构函数,销毁栈{delete[]base;stacksize = 0;}SElemType GetTop();//取栈顶元素void Push(SElemType e);//进栈void Pop(SElemType& e);//退栈int EmptyStack();//判断栈空否,若空返回1,否则返回0void Print();//从栈底到栈顶输出栈中的元素
};

🔭3.2初始化建立空栈

Sqstack::Sqstack()
{base = top = new SElemType[InitStackSize];stacksize = InitStackSize;
}

🔭3.3入栈操作

void Sqstack::Push(SElemType e)
{if (top - base == stacksize){SElemType* base1 = new SElemType[stacksize + StackIncrement];int i = 0;for (i = 0; i < InitStackSize; i++){base1[i] = base[i];}delete[]base;//释放空间base = base1;top = base + stacksize;stacksize += StackIncrement;}*top++ = e;//插入e
}

🔭3.4退栈操作

void Sqstack::Pop(SElemType& e)
{if (top == base)//栈空,删除操作无法进行return;e = *top--;
}

🔭3.5栈判空操作

int Sqstack::EmptyStack()
{if (top == base)return 1;elsereturn 0;
}

🔭3.6返回栈顶元素

SElemType Sqstack::GetTop()//返回栈顶元素
{return *(top - 1);
}

🔭3.7打印栈

void Sqstack::Print()//打印栈中元素
{int i = 0;for (i = 0; i < *(top - 2); i++){cout << base[i] << " ";}cout << endl;
}

🔭3.8全部代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
#define InitStackSize 100
#define StackIncrement 10
typedef int SElemType;
class Sqstack
{
private:SElemType* base;//栈底指针,SElemType为栈中元素类型SElemType* top;//栈顶指针int stacksize;//栈容量
public:Sqstack();//构造函数,初始化建立一空栈~Sqstack()//析构函数,销毁栈{delete[]base;stacksize = 0;}SElemType GetTop();//取栈顶元素void Push(SElemType e);//进栈void Pop();//退栈int EmptyStack();//判断栈空否,若空返回1,否则返回0void Print();//从栈底到栈顶输出栈中的元素
};
Sqstack::Sqstack()
{base = top = new SElemType[InitStackSize];stacksize = InitStackSize;
}
void Sqstack::Push(SElemType e)
{if (top - base == stacksize){SElemType* base1 = new SElemType[stacksize + StackIncrement];int i = 0;for (i = 0; i < InitStackSize; i++){base1[i] = base[i];}delete[]base;//释放空间base = base1;top = base + stacksize;stacksize += StackIncrement;}*top++ = e;//插入e
}
void Sqstack::Pop()
{SElemType e;if (top == base)//栈空,删除操作无法进行return;e = *top--;
}
int Sqstack::EmptyStack()//判空函数
{if (top == base)return 1;elsereturn 0;
}
SElemType Sqstack::GetTop()//返回栈顶元素
{cout << *(top - 1) << endl;return 0;
}
void Sqstack::Print()//打印栈中元素
{int i = 0;for (i = 0; i < *(top - 2); i++){cout << base[i] << " ";}cout << endl;
}
int main()
{Sqstack l;l.Push(3);l.Push(5);l.Push(6);l.Pop();l.GetTop();l.Print();return 0;
}

✅调试运行:
在这里插入图片描述

🎈4.链栈

链栈是指利用一组地址任意的存储空间存放栈中元素的存储结构,这里使用链表来实现链栈。链栈的存储结构如下图所示:
在这里插入图片描述
注:top指向头结点,a1为栈顶元素,an为栈底元素,栈的所有操作都在单链表的表头进行。

🔭4.1链栈的类定义

typedef int SElemType;
typedef struct LinkNode
{SElemType data;LinkNode* next;
}LinkNode;
class LinkStack
{
private:LinkNode* top;//栈顶指针即链栈的头指针
public:LinkStack();//构造函数,置空链栈~LinkStack();//析构函数,释放链栈中各结点的存储空间SElemType GetTop();//获取栈顶元素void Push(SElemType e);//将元素e入栈void Pop(SElemType& e);//将栈顶元素出栈int EmptyStack();//判断链栈是否为空栈
};

🔭4.2创建空栈

LinkStack::LinkStack()
{top = new LinkNode;top->next = NULL;
}

🔭4.3销毁栈

LinkStack::~LinkStack()//析构函数,释放链栈中各结点的存储空间
{LinkNode* p = top;LinkNode* q = top->next;while (q){delete p;p = q;q = q->next;}delete p;//删除最后一个结点
}

🔭4.4入栈操作

void LinkStack::Push(SElemType e)
{LinkNode* s = new LinkNode;//分配空间s->data = e;s->next = top->next;//插入元素etop->next = s;
}

🔭4.5退栈操作

void LinkStack::Pop(SElemType& e)
{if (top->next == NULL)return;LinkNode* p = top->next;//p指向首元结点e = p->data;top->next = p->next;//删除首元结点delete p;
}

🔭4.6判空操作

int LinkStack::EmptyStack()
{if (top->next == NULL)return 1;else return 0;//栈非空返回0
}

🔭4.7返回栈顶元素

SElemType LinkStack::GetTop()
{return top->next->data;
}

🔭4.8打印栈

void LinkStack::print()
{LinkNode* p = top->next;while (p){cout << p->data << " ";p = p->next;}cout << endl;
}

🔭4.9全部代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
typedef int SElemType;
typedef struct LinkNode
{SElemType data;LinkNode* next;
}LinkNode;
class LinkStack
{
private:LinkNode* top;//栈顶指针即链栈的头指针
public:LinkStack();//构造函数,置空链栈~LinkStack();//析构函数,释放链栈中各结点的存储空间SElemType GetTop();//获取栈顶元素void Push(SElemType e);//将元素e入栈void Pop();//将栈顶元素出栈int EmptyStack();//判断链栈是否为空栈void print();//打印栈
};
LinkStack::LinkStack()//构造函数,置空链栈
{top = new LinkNode;top->next = NULL;
}
LinkStack::~LinkStack()//析构函数,释放链栈中各结点的存储空间
{LinkNode* p = top;LinkNode* q = top->next;while (q){delete p;p = q;q = q->next;}delete p;//删除最后一个结点
}
void LinkStack::Push(SElemType e)
{LinkNode* s = new LinkNode;//分配空间s->data = e;s->next = top->next;//插入元素etop->next = s;
}
void LinkStack::Pop()
{SElemType e;if (top->next == NULL)return;LinkNode* p = top->next;//p指向首元结点e = p->data;top->next = p->next;//删除首元结点delete p;
}
int LinkStack::EmptyStack()
{if (top->next == NULL)return 1;else return 0;//栈非空返回0
}
SElemType LinkStack::GetTop()
{cout << top->next->data << endl;return 0;
}
void LinkStack::print()
{LinkNode* p = top->next;while (p){cout << p->data << " ";p = p->next;}cout << endl;
}
int main()
{LinkStack l;l.Push(1);l.Push(2);l.Push(3);l.Push(4);l.Push(5);l.GetTop();l.Pop();l.print();
}

✅运行示例:
在这里插入图片描述

好啦,关于栈的知识到这里就结束啦,后期会继续更新数据结构与算法的相关知识,欢迎大家持续关注、点赞和评论!❤️❤️❤️

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

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

相关文章

MyBatis的缓存,一级缓存,二级缓存

10、MyBatis的缓存 10.1、MyBatis的一级缓存 一级缓存是SqlSession级别的&#xff0c;通过同一个SqlSession对象 查询的结果数据会被缓存&#xff0c;下次执行相同的查询语句&#xff0c;就 会从缓存中&#xff08;缓存在内存里&#xff09;直接获取&#xff0c;不会重新访问…

Centos下编译ffmpeg动态库

文章目录 一、下载ffmpeg安装包二、编译ffmpeg三、安装yasm 一、下载ffmpeg安装包 下载包 wget http://www.ffmpeg.org/releases/ffmpeg-4.4.tar.gz解压 tar -zxvf ffmpeg-4.4.tar.gz二、编译ffmpeg 进入解压的目录 cd ffmpeg-4.4编译动态库 ./configure --enable-shared…

关于pytorch不区分行向量与列向量的理解

听李沐老师讲深度学习时候解释pytorch不区分行向量和列向量&#xff0c;只相当于是一维数组&#xff0c;一维张量一定是行向量&#xff0c;相当于数组&#xff0c;而行列向量可以放到矩阵中看。 测试如下&#xff1a; rtorch.tensor([1,2,3],dtypetorch.float32) print(r,r.T…

Redis五大数据类型的底层设计

SDS 无论是 Redis 的 Key 还是 Value&#xff0c;其基础数据类型都是字符串。虽然 Redis是使用标准 C 语言开发的&#xff0c;但并没有直接使用 C 语言中传统的字符串表示&#xff0c;而是自定义了一 种字符串。这种字符串本身的结构比较简单&#xff0c;但功能却非常强大&…

Master PDF Editor v5.9.70便携版

软件介绍 Master PDF Editor中文版是一款小巧的多功能PDF编辑器,可以轻松查看,创建,修改,批注,签名,扫描,OCR和打印PDF文档.高级注释工具,可以添加任意便笺指示对象突出显示,添加下划线和删除,而无需更改源PDF文件. 软件截图 更新日志 code-industry.net/what-is-new-in-mas…

4.1 继承性

知识回顾 &#xff08;1&#xff09;类和对象的理解&#xff1f; 对象是现实世界中的一个实体&#xff0c;如一个人、一辆汽车。一个对象一般具有两方面的特征&#xff0c;状态和行为。状态用来描述对象的静态特征&#xff0c;行为用来描述对象的动态特征。 类是具有相似特征…

goland 旧版本使用1.19环境

C:\Go\src\runtime\internal\sys\zversion.go // Code generated by go tool dist; DO NOT EDIT.package sysconst StackGuardMultiplierDefault 1const TheVersion go1.19引入其他包的标识符 package mainimport ("fmt""gotest/test")func main() {f…

Flask (Jinja2) 服务端模板注入漏洞复现

文章目录 Flask (Jinja2) 服务端模板注入漏洞1.1 漏洞描述1.2 漏洞原理1.3 漏洞危害1.4 漏洞复现1.4.1 漏洞利用 1.5 漏洞防御 Flask (Jinja2) 服务端模板注入漏洞 1.1 漏洞描述 说明内容漏洞编号漏洞名称Flask (Jinja2) 服务端模板注入漏洞漏洞评级高危影响版本使用Flask框架…

Linux友人帐之调试器--gdb的使用

一、debug和realease版本的区别 区别 debug是给程序员用的版本&#xff0c;添加了调试信息&#xff0c;用于解决软件或程序中出现的问题&#xff0c;realease是发行给客户使用的版本&#xff0c;并未添加调试信息&#xff0c;只需要给客户提供优越的产品使用环境即可&#xff…

数据库系统概论学习 1 绪论

1.1.1 数据、数据库、数据库管理系统、数据库系统 一、数据 Data 数据是数据库中存储的基本对象 定义&#xff1a;描述事物的符号记录称为数据&#xff0c;描述事物的符号可以是数字、文字、图像、图形、声音、语言等表现形式&#xff0c;它们都可以经过数字化后存入计算机。…

【C++进阶】:C++类型转换

C类型转换 一.C语言里的类型转换二.C语音类型转换的一些弊端三.C的四种类型转换1.static_cast2.reinterpret_cast3.const_cast4.dynamic_cast 一.C语言里的类型转换 在C语言中&#xff0c;如果赋值运算符左右两侧类型不同&#xff0c;或者形参与实参类型不匹配&#xff0c;或者…

ST‐LINK V2 使用说明(安装,调试,烧录)

目录 1. 初识 ST-LINK V2 1.1 ST-LINK V2 简介 2. ST-LINK V2 驱动的安装与固件升级 2.1 驱动的安装 2.2 固件的升级 3. 使用 STM32 ST-LINK Utility 烧写目标板 hex 3.1 ST-LINK 烧写 hex 文件 4.使用 ST-LINK V2 调试 STM8 4.1 ST‐LINK 调试 STM8 5.…

String方法:分割、梦回C语言,格式化输出format

String poem "锄禾日当午&#xff0c;汗滴禾下土&#xff0c;谁知盘中餐&#xff0c;粒粒皆辛苦";String[] split poem.split("&#xff0c;");System.out.println("悯农");for (int i 0; i < split.length; i) {System.out.println(split…

53 打家劫舍

打家劫舍 题解1 DP1题解2 DP2 &#xff01;经典DP&#xff01; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果 两间相邻的房屋在同一晚上被小偷闯入…

【C++】继承 -- 详解

一、继承的概念及定义 1、继承的概念 继承 (inheritance) 机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保 持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。 继承呈现了面向对象 程序设…

【Vue】vue2与netcore webapi跨越问题解决

系列文章 C#底层库–记录日志帮助类 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/124187709 文章目录 系列文章前言一、技术介绍二、问题描述三、问题解决3.1 方法一&#xff1a;前端Vue修改3.2 方法二&#xff1a;后端允许Cors跨越访问 四、资源…

前端TypeScript学习day04-交叉类型与泛型

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 交叉类型 泛型 创建泛型函数 调用泛型函数&#xff1a; 简化调用泛型函数&#xff1a; 泛型约束 指定…

浅谈MDK, IAR,CLANG和GCC的局部变量字节对齐处理差异(2023-10-13)

视频&#xff1a; https://www.bilibili.com/video/BV1CB4y1Z7kA 浅谈MDK, IAR, CLANG和GCC的局部变量字节对齐处理差异 问题由来&#xff1a; 早期这个帖子里面的局部变量对齐仅测试了MDK AC5&#xff0c;但项目中使用AC6发现了新问题&#xff0c;看来AAPCS规约研究的还是不…

centos 里面的service自启动app.jar,出现两个java进程,app是同一个端口

当使用jps -lv查看java虚拟机进程 app.jar启动后&#xff0c;居然出现两个启动进程&#xff0c;而且他们的端口都一样&#xff0c;同一端口&#xff0c;是不允许启动两个相同app的。 使用进程ps查看进程工具 #ps -aux 参数说明&#xff1a; a: 显示跟当前终端关联的所有进…

《Deep Residual Learning for Image Recognition》阅读笔记

论文标题 《Deep Residual Learning for Image Recognition》 撑起CV界半边天的论文Residual &#xff1a;主要思想&#xff0c;残差。 作者 何恺明&#xff0c;超级大佬。微软亚研院属实是人才辈出的地方。 初读 摘要 提问题&#xff1a; 更深层次的神经网络更难训练。 …