C++数据结构-栈

目录

    • 顺序栈
    • 链栈

栈是允许在表的一端进行插入和删除的线性表。表中允许插入删除的一端是栈顶,栈顶的当前位置是动态变化的;不允许插入和删除的一端是栈底,栈底的位置是不变的。当表中没有元素时称为空栈,插入数据的运算称为进栈、压栈、入栈,删除数据的运算称为出栈或退栈。

进/出栈示意图:
在这里插入图片描述进栈的顺序是e1、e2、e3,出栈的顺序为e3、e2、e1,所以栈又称为后进先出线性表(Last In First Out),简称LIFO表,或称先进后出线性表。其特点是先进后出或者后进先出。

顺序栈

栈的存储与一般的线性表的存储类似,主要有两种存储方式:顺序存储和链式存储。

利用顺序存储方式实现的栈称为顺序栈。类似于顺序表的定义,要分配一块连续的存储空间存放栈中的元素,栈底位置可以固定地设置在数组的任何一端(一般在下标为0的一端),而栈顶是随着插入和删除而变化的,再用一个变量指明当前栈顶的位置(实际上是栈顶元素的下一个位置)。

在这里插入图片描述顺序栈的类描述如下:

// 学生表
struct Student
{int					id_;		// 学生idstd::string			name_;		// 学生姓名int					score_;		// 学生成绩Student(int _id, std::string _name, int _score): id_(_id), score_(_score), name_(_name){}Student(): id_(0), score_(0){}
};class Stack
{
public:Stack(int _stackSize = 100);~Stack();bool IsEmptyStack();	// 判断栈是否为空bool PushStack(Student &_stu);		// 入栈bool PopStack(Student &_stu);		// 出栈bool GetTop(Student& _stu);			// 取栈顶元素private:Student* base_;	// 栈底指针Student* top_;	// 栈顶指针int size_;		// 栈的大小
};

(1)判断栈是否为空

算法思想:判断top_是否小于等于base_,如果小于等于说明是空栈,返回true,否则返回false。

bool Stack::IsEmptyStack()
{if (top_ <= base_)return true;return false;
}

(2)入栈操作

算法描述:入栈操作是在栈的顶部进行插入操作,相当于在顺序表的表尾进行插入,因而无须移动元素。

算法思想:首先判断栈是否已满,若满则失败,返回0;否则,由于栈的top 指向栈顶元素的后一个位置,将入栈元素赋到top的位置,再将top+1指向新的位置,成功返回1。

bool Stack::PushStack(Student& _stu)
{if (top_ - base_ < size_){*top_ = _stu;top_++;return true;}return false;
}

(3)出栈操作

算法描述:出栈操作是在栈的顶部进行,相当于是删除顺序表的最后一个元素,所以也不需要移动元素。

算法思想:首先判断栈是否为空,若空则失败,返回false;否则,由于栈的top 指向栈顶元素的后一位置,要先修改top为top-1,再将其所指向的元素以引用参数_stu返回,成功返回true。

bool Stack::PopStack(Student& _stu)
{if (top_ > base_){top_--;_stu = *top_;return true;}return false;
}

(4)取栈顶元素

算法描述:取栈顶元素是获取出栈顶元素的值,而不改变栈。

算法思想:首先判断栈是否为空,若空则失败,返回0;否则,由于栈的top 指向栈顶元素的后一位置,返回top-1所指单元的值,栈不发生变化。

bool Stack::GetTop(Student& _stu)
{if (top_ <= base_)return false;_stu = *(top_ - 1);return true;
}

链栈

栈也可以用链式存储方式实现。一般链栈用单链表表示,其结点结构与单链表的结构相同,即结点为:

// 学生表
struct Student
{int					id_;		// 学生idstd::string			name_;		// 学生姓名int					score_;		// 学生成绩Student(int _id, std::string _name, int _score): id_(_id), score_(_score), name_(_name){}Student(): id_(0), score_(0){}
};//定义链栈的结点
class StackNode                        
{
public:Student data;StackNode* next;StackNode(){next = NULL;};
};

因为栈中的主要运算是在栈顶进行插入和删除操作,显然在单链表的表头插入和删除都比较方便,因此以其作为栈顶,而且没有必要像单链表那样为了运算方便而附加一个头结点,存储结构如图:

在这里插入图片描述思考:为什么不用单链表的表尾作为栈顶?

因为用表尾作为栈顶,那么每次进行入栈、出栈、取栈顶元素的操作都需要遍历一遍单链表找到表尾,或者声明尾指针指向表尾,但是这样做太复杂,没有必要。

// 链栈
class LinkStack
{
public:LinkStack();~LinkStack();bool Empty_Stack();							//判断栈是否为空bool Push_Stack(Student e);					//将元素e插入栈顶bool Pop_Stack(Student& e);					//从栈顶删除一个元素到e中返回bool GetTop_Stack(Student& e);				//从栈顶取出一个元素到e中返回private:StackNode* top_;};            

(1)判断链栈是否为空

bool LinkStack::Empty_Stack()
{return (top_ == nullptr);
}

(2)入栈操作

入栈操作相当于是在表头插入一个元素

bool LinkStack::Push_Stack(Student e)
{StackNode* p = new StackNode;p->data = e;p->next = top_;top_ = p;return true;
}

(3)出栈操作

出栈操作相当于删除表头

bool LinkStack::Pop_Stack(Student& e)
{if (top_){StackNode* p = top_;e = p->data;top_ = p->next;delete p;p = nullptr;return true;}return false;
}

(4)取栈顶元素

bool LinkStack::GetTop_Stack(Student& e)
{if (top_){e = top_->data;return true;}return false;
}

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

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

相关文章

【STM32F103】SysTick系统定时器延时函数

SysTick SysTick是Cortex-M3内核中的一个外设&#xff0c;内嵌在NVIC中&#xff0c;叫系统定时器。 当处理器在调试期间被喊停时&#xff0c;SysTick也将暂停运作。 一共有四个寄存器&#xff0c;不过我们通常用前三个&#xff0c;不需要校准。下图出自《STM32F10xxx Cortex…

35--JDK新特性

1、新语法结构 新的语法结构&#xff0c;为我们勾勒出了 Java 语法进化的一个趋势&#xff0c;将开发者从复杂、繁琐的低层次抽象中逐渐解放出来&#xff0c;以更高层次、更优雅的抽象&#xff0c;既降低代码量&#xff0c;又避免意外编程错误的出现&#xff0c;进而提高代码质…

Linux软件包管理器——yum命令

如何使用yum 一、快速认识yum(简单介绍)二、快速使用yum2.1 rzsz2.2 linux命令行小游戏和彩蛋 三、yum的整个生态问题 一、快速认识yum(简单介绍) Linux中我们也要进行工具/指令/程序&#xff0c;安装&#xff0c;检查卸载等&#xff0c;需要yum的软件 安装软件的方式&#xf…

<Icon-ResizER>support

If you get any questions in using app, email me caohechunhotmail.com.

Unity坦克大战开发全流程——开始场景——排行榜数据逻辑

开始场景——排行榜数据逻辑 排行榜单条数据 排行榜列表 然后在数据管理类中声明一个对应的字段 初始化数据 然后再在上一节课所编写的UpdatePanelInfo函数中处理数据更新的逻辑 时间换算算法 然后再在数据管理类中编写一个在排行榜中添加数据的方法以提供给外部 直到当前RankI…

Python压缩图片大小

今天遇到一个问题&#xff0c;制作的网站因为图片尺寸比较大导致加载很慢&#xff0c;所以想通过压缩图片的方式来加快页面的加载速度&#xff08;当然也可以选择cdn和oss的方式来加快页面加载速度&#xff09; 话不多说&#xff0c;Python肯定是首选项嘛&#xff0c;那么PIL&…

深度学习核心技术与实践之计算机视觉篇

非书中全部内容&#xff0c;只是写了些自认为有收获的部分 计算机视觉背景 &#xff08;1&#xff09;视觉皮层的神经元是一列一列组织起来的&#xff0c;每一列神经元只喜欢某一种特定的形状或者某些简单的线条组合&#xff0c;而不是鱼、老鼠、鲜花 &#xff08;2&#xf…

【Linux】Linux 下基本指令 -- 详解

无论是什么命令&#xff0c;用于什么用途&#xff0c;在 Linux 中&#xff0c;命令有其通用的格式&#xff1a; command [-options] [parameter] command&#xff1a;命令本身。-options&#xff1a;[可选&#xff0c;非必填]命令的一些选项&#xff0c;可以通过选项控制命令的…

EBU7140 Security and Authentication(二)非对称加密;授权

B2 非对称加密介绍 前面的传统加密算法都是对称加密。就是加密解密用一个密钥。非对称加密就是用不同的密钥&#xff0c;加密复杂度更高。 Diffie-Hellman 密钥交换法 一种密钥交换方法。 common 是公共基础颜色&#xff0c;secret 是各自私有颜色&#xff0c;公共颜色和自己…

【产品设计】信息建设三驾马车:MES系统拆解

本篇文章&#xff0c;将从三个方面对MES系统进行拆解分析&#xff0c;并分析其特殊功能——文档管理。MES系统能实现多个生产信息的互联互通&#xff0c;提高生产效率。 MES系统主要实现生产业务系统管理。 ERP系统主要实现采购、销售、库存&#xff08;进销存&#xff09;、财…

算法基础之滑雪

滑雪 核心思想&#xff1a;记忆化搜索 状态表示&#xff1a; f[i][j] 表示所有从(i,j) 开始滑的路径的最大值 状态计算&#xff1a; 分成四个方向 f[i][j] max(f[i][j] , f[i][j1] 1) 且h[a][b] (下一个点) 必须严格小于 h[i][j] 才能滑过去 #include<iostream>#…

大数据背景下基于联邦学习的小微企业信用风险评估研究

摘要&#xff1a; 小微企业信用风险评估难是制约其融资和发展的一个主要障碍。基于大数据的小微企业信用风险评估依然面临着单机构数据片面、跨机构数据共享难、模型不稳定等诸多挑战。针对相关问题和挑战&#xff0c;本项目拟在多主体所有权数据隐私保护与安全共享的背景下&am…