当前位置: 首页 > news >正文

线性表之栈

1. 栈

1.1 栈的由来

对于大多数人而言都对生活充满了热爱,如果对身边接触到的各种事物仔细观察就会发现它们有很多相似的特性:

  • 给子弹上弹夹,先压进去的最后被发射出来,最后压进去的第一个被发射出来。
  • 浏览器的后退键,第一次后退看到的是最后浏览的页面,最后一次后退看到的是第一次浏览的页面
  • 带编辑功能的软件,比如:Office、Photoshop、IDE,第一次撤销得到的最后一次修改的内容,最后一次撤销得到的是第一次修改的内容
  • 如果在以上的某一个场景下进行连续的操作,按照线性表的描述我们就可以得到一个从前到后的序列,并且在访问序列中的元素的时候是按照从后往前的顺序进行的。

如果对线性表中元素的访问进行了限制,那么这个线性表就被称作受限制的线性表。常用的受限制的线性表有栈和队列。

栈(Stack)是一种常见的数据结构,它遵循后进先出(Last In First Out,LIFO)的原则,即最新添加的元素最先被移除,也就是它要求仅能在表尾进行元素的插入和删除。

关于栈有几个相关的概念需要大家掌握:

  • 栈顶: 线性表允许插入、删除的一端被称为栈顶
  • 栈底: 线性表不允许插入、删除的一端被称为栈底
  • 压栈: 将数据添加到栈顶,也叫进栈、入栈
  • 弹栈: 将数据从栈顶删除,也叫出栈
  • 空栈: 不含任何元素的栈叫做空栈

1.2 栈的存储结构

因为线性表有两种存储结构顺序存储结构和链式存储结构,所以对于栈而言也有两种存储结构,分别是顺序栈和链式栈。

顺序栈:

  • 基于数组实现,具有固定的大小。
  • 优点是实现简单,访问元素速度快,但需要预先知道栈的最大容量。

链式栈:

  • 基于链表实现(使用单向链表即可),没有固定大小限制,可以动态扩展。
  • 优点是可以灵活地处理大小变化,但实现相对复杂,且在链表节点上有额外的内存开销。

2. 顺序栈

2.1 栈顶在哪儿?

前面也说到了,顺序栈是通过数组来实现的,假设我们要存储整形数据,那么在实现顺序栈的时候,准备一个整形数组即可。

根据栈的特性,只能对栈顶进行操作,那么对于数组而言栈顶在哪儿呢?有两种解决方案,下面我们来一起分析一下它们的可行性:

数组的头部做栈顶,尾部做栈底

  • 入栈:每次入栈数组中所有的旧元素需要后移,时间复杂度O(n)

  • 出栈:每次出栈数组中所有的剩余元素需要前移,时间复杂度O(n)

        上图的出栈顺序为9、1、2、3、4、5、6、7、8

数组的尾部做栈顶,头部做栈底

  • 入栈:直接将数据添加到数组尾部,不涉及到元素移动,时间复杂度O(1)

        上图的入栈顺序为1、2、3、4、5、6、7、8、9

  • 出栈:直接将数据从数组尾部删除,不涉及到元素移动,时间复杂度O(1)

        上图的出栈顺序为9、8、7、6、5、4、3、2、1

所以现在可以得到一个结论:如果是顺序栈,选择数组的尾部作为栈顶,操作效率是最高的,时间复杂度为 O(1)。

2.2 顺序栈的实现

我们先定义一个C++的类,来实现这个顺序栈。

头文件

// ArrayStack.h
#pragma once
const int MAX_SIZE = 100;class ArrayStack 
{
public:ArrayStack();bool isEmpty();bool isFull();// 压栈void push(int x); // 出栈int pop();// 得到栈顶元素int top();
private:int m_data[MAX_SIZE];int m_top;
};
  • const int MAX_SIZE = 100:整形常量,设置栈的最大容量为100
  • int m_top:类的私有成员,栈顶指针,用来描述可存储数据的栈顶元素在数组中的位置(数组末尾元素的下一个位置)。

源文件

// ArrayStack.cpp
#include <iostream>
#include "ArrayStack.h"
using namespace std;ArrayStack::ArrayStack() : m_top(0) {}bool ArrayStack::isEmpty() 
{return m_top == 0;
}bool ArrayStack::isFull() 
{return m_top == MAX_SIZE;
}void ArrayStack::push(int x) 
{if (isFull()) {cout << "栈已经满了, 数据无法入栈!" << endl;return;}m_data[m_top++] = x;
}int ArrayStack::pop() 
{if (isEmpty()) {cout << "空栈, 无法弹出元素!" << endl;return -1;}return m_data[--m_top];
}int ArrayStack::top() 
{if (isEmpty()) {cout << "空栈, 无法访问栈顶元素!" << endl;return -1;}return m_data[m_top - 1];
}int main() 
{ArrayStack stack;stack.push(1);stack.push(2);stack.push(3);cout << "栈顶元素: " << stack.top() << endl;stack.pop();cout << "新的栈顶元素: " << stack.top() << endl; return 0;
}

通过代码可以看到顺序栈的实现是非常简单的,其实就是对数组的操作位置和操作方式进行了限制,通过选择合适的栈顶位置,提高了栈的工作效率。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • python无法连接SQL SERVER问题解决
  • fedora siliverblue adb
  • python---爬取QQ音乐
  • python办公自动化:使用`Python-PPTX`自动化与批量处理
  • 防御网站数据爬取:策略与实践
  • [手机Linux PostmarketOS]六, mySQL安装和使用
  • 关于谷歌账号的三个“错误的”问题:谷歌有客服吗?登录不了的账号如何注销?登录不了的账号绑定的手机还能注册新账号吗?
  • 2024/9/4黑马头条跟学笔记(二)
  • Linux【6】系统
  • b站批量取消关注
  • 在Ubuntu 20.04上安装MySQL的方法
  • C和C++的内存管理
  • EmguCV学习笔记 C# 10.1 人脸检测 CascadeClassifier类
  • 微软发布Phi-3.5 SLM,附免费申请试用
  • HUAWEI华为MateBook B5-420 i5 集显(KLCZ-WXX9,KLCZ-WDH9)原装出厂Windows10系统文件下载
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • CEF与代理
  • javascript面向对象之创建对象
  • js ES6 求数组的交集,并集,还有差集
  • Python 反序列化安全问题(二)
  • spring-boot List转Page
  • SpringCloud集成分布式事务LCN (一)
  • ubuntu 下nginx安装 并支持https协议
  • Web设计流程优化:网页效果图设计新思路
  • Yeoman_Bower_Grunt
  • 从零开始在ubuntu上搭建node开发环境
  • 代理模式
  • 对象管理器(defineProperty)学习笔记
  • 扑朔迷离的属性和特性【彻底弄清】
  • 思考 CSS 架构
  • 一道闭包题引发的思考
  • ionic异常记录
  • ‌前端列表展示1000条大量数据时,后端通常需要进行一定的处理。‌
  • #、%和$符号在OGNL表达式中经常出现
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (C++)八皇后问题
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (Git) gitignore基础使用
  • (Qt) 默认QtWidget应用包含什么?
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (第27天)Oracle 数据泵转换分区表
  • (二)Eureka服务搭建,服务注册,服务发现
  • (二)pulsar安装在独立的docker中,python测试
  • (二)正点原子I.MX6ULL u-boot移植
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • .NET成年了,然后呢?
  • .Net多线程Threading相关详解
  • .Net面试题4
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示
  • /etc/sudoers (root权限管理)
  • @modelattribute注解用postman测试怎么传参_接口测试之问题挖掘
  • @TableLogic注解说明,以及对增删改查的影响