数据结构与算法-栈

在这里插入图片描述

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

  • 🎈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.mzph.cn/news/105616.shtml

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

相关文章

物联网市场规模迅速增加,在交通、医疗、农业等方面发展势头迅猛

物联网&#xff08;Internet of things&#xff09;是一系列用于解决物的信息识别、交换、控制等技术的集合应用形成的网络。当连接从互联网时代的人与人走向万物互联&#xff0c;万物的数字化、智能化依赖物联网技术。因此&#xff0c;物联网是指利用各类信息识别设备&#xf…

Ceph介绍与部署

Ceph介绍与部署 一、存储基础1.1、单机存储设备1.1.1、单机存储的问题 1.2、商业存储解决方案1.3、分布式存储&#xff08;软件定义的存储 SDS&#xff09;1.3.1、分布式存储的类型 二、Ceph 简介三、Ceph 优势四、Ceph 架构五、Ceph 核心组件5.1、Pool中数据保存方式支持两种类…

Vue2实现图片预览功能 -- v-viewer:图片查看器

一. 先看效果图 二. 具体步骤 简介&#xff1a;一款基于 viewer.js 封装的Vue版插件&#xff0c;可用于图像查看&#xff0c;以及图片的旋转、缩放等功能预览 官网&#xff1a;v-viewer 文档说明&#xff1a;Vue图片浏览组件v-viewer&#xff0c;支持旋转、缩放、翻转等操作 - …

Ultra-Fast-Lane-Detection-v2 裁剪数据增强

目录 标注拆分为独立文件加载并数据增强 Ultra-Fast-Lane-Detection-v2 裁剪数据增强 main方法是调用示例

Android Studio的笔记--HttpURLConnection使用GET下载zip文件

HttpURLConnection使用GET下载zip文件 http get下载zip文件MainActivity.javaAndroidMainfest.xmlactivity_main.xmllog http get下载zip文件 MainActivity.java 用HttpURLConnection GET方法进行需注意&#xff1a; 1、Android 9及以上版本需要设置这个&#xff0c;否则会有…

网络爬虫实践小结

背景 近期工作中要解决两个问题&#xff0c;一个是数据组需要网爬一些图片数据&#xff0c;另外一个是要批量爬取公司用于文档协同的一个网站上的附件。于是乎&#xff0c;就写了两个脚本去完成任务。 爬虫思路 第一步&#xff1a;向确定的url发送请求&#xff0c;接收服务器…

[小林coding]4.2TCP重传,滑动窗口,流量控制,拥塞控制_1013

1.重传 1.1 超时重传 两个情况&#xff1a; a 数据包丢失 b ack应答丢失 RTT&#xff1a;网络包往返的时间&#xff08;不是一个定值&#xff09; RTO&#xff1a;超时重传的时间间隔&#xff08;也是一个动态的&#xff09; RTO设置的时间长&#xff1a;浪费时间资源&…

grafana api创建dashboard 记录

文章目录 json model导入申请api key创建dashboard删除dashboard json model导入 直接在ui通过json model 导入&#xff0c;开发自己用还好&#xff0c;但对非开发人员不太友好&#xff0c;故考虑通过api后台自动创建 api doc : https://grafana.com/docs/grafana/v9.3/devel…

AR动态贴纸SDK,让创作更加生动有趣

在当今的社交媒体时代&#xff0c;视频已经成为了人们表达自我、分享生活的重要方式。然而&#xff0c;如何让你的视频在众多的信息中脱颖而出&#xff0c;吸引更多的关注和点赞呢&#xff1f;答案可能就在你的手中——美摄AR动态贴纸SDK。 美摄AR动态贴纸SDK是一款专为视频编辑…

R语言——赋值(= ,<- ,<<-)

R语言 R语言——赋值&#xff08; &#xff0c;<- &#xff0c;<<-&#xff09; 文章目录 R语言一、 与 <- 的区别二、 <<- ,向上一环境层写入变量 R语言中" <- " 与 " " 都可以用来赋值&#xff0c;但R中建议使用" <- “…

ESP32网络开发实例-UDP数据发送与接收

UDP数据发送与接收 文章目录 UDP数据发送与接收1、UDP简单介绍2、软件准备3、硬件准备4、代码实现本文将详细介绍在Arduino开发环境中,如何实现ESP32通过UDP协议进行数据发送与接收。 1、UDP简单介绍 用户数据报协议 (UDP) 是一种跨互联网使用的通信协议,用于对时间敏感的传…

Linux开发工具:vim的介绍和用法及其简单配置

前言 Vim 简介. 编辑. Vim是从 vi 发展出来的一个文本编辑器。. 代码补全、编译及错误跳转等方便编程的功能特别丰富&#xff0c;在程序员中被广泛使用&#xff0c;和Emacs并列成为类Unix系统用户最喜欢的文本编辑器。. [1] vim的设计理念是命令的组合。. 用户学习了各种各样的…

【统计学概念】初学者指南:了解置信区间

一、说明 什么是置信区间&#xff1f;如何将概率转化成信心度&#xff1f;信心度如何去工作&#xff1f;这些初步的统计概念需要明晰&#xff0c;然后才能应用统计模型&#xff0c;然后是贝叶斯推理&#xff0c;我们将逐步深入这些概念。 二、总体与样本个体统计 总体是研究人…

【Unity】【VR】详解Oculus Integration输入

【背景】 以下内容适用于Oculus Integration开发VR场景,也就是OVR打头的Scripts,不适用于OpenXR开发场景,也就是XR打头Scripts。 【详解】 OVR的Input相对比较容易获取。重点在于区分不同动作机制的细节效果。 OVR Input的按键存在Button和RawButton两个系列 RawButton…

比较和同步数据库架构和数据:MssqlMerge Pro Crack

比较和同步数据库架构和数据 适用于Oracle、MySQL 和 MariaDB、SQL Server、PostgreSQL、SQLite、MS Access和跨 DBMS 场景 业界领先的文本比较工具中常用的两面板 UI 快速过滤器显示所有/新/更改/新更改 合并两个方向的更改 轻量级&#xff1a;跨 DBMS 工具小于 20 MB&#xf…

数据结构之手撕顺序表(增删查改等)

0.引言 在本章之后&#xff0c;就要求大家对于指针、结构体、动态开辟等相关的知识要熟练的掌握&#xff0c;如果有小伙伴对上面相关的知识还不是很清晰&#xff0c;要先弄明白再过来接着学习哦&#xff01; 那进入正题&#xff0c;在讲解顺序表之前&#xff0c;我们先来介绍…

代码随想录——图论一刷day03

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣130. 被围绕的区域二、力扣417. 太平洋大西洋水流问题三、力扣827. 最大人工岛 前言 一、力扣130. 被围绕的区域 class Solution {boolean[][] flag;i…

JavaScript-es6-新版语法-export-import

文章目录 1.export2.import3.export default 命令4.总结 在JavaScript ES6中&#xff0c;export与export default均可用于导出常量、函数、文件、模块等。模块功能主要由两个命令构成&#xff1a;export和import。export命令用于规定模块的对外接口&#xff0c;import命令用于输…

接口测试文档

接口测试的总结文档 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系。但该部分只交代了怎么做和如何做&#xff1f;并没有解释为什么要做&#xff1f; 第二部分&#xff1a;主要介绍为什…

鸿蒙tabbar ArkTS

鸿蒙tabbar ArkTS 做了仿照现在应用的做了一个tabbar。 官方文档地址 参考文档 tabbar 其中有个比较重要的点是&#xff0c;对image资源的引用问题。 资源相关说明 图片是resources目录下的base目录下的。 media目录下的图片的资源不能添加文件夹&#xff0c;只能是文件&a…