栈(stack)的那些事

1.1栈的简介

栈作为一种限制性访问数据结构,提供了push()压入和pop()弹出的方法,具有后进先出的特点,使得程序不容易出错。 关于栈的实现,输入的入栈和出栈的时间复杂度为O(1)。操作时间不依赖总体栈中的个数,因此操作时间非常快。

1.2 栈的Java实现

这里用底层数组用Object主要为了能存储不同对象,默认初始化数组大小为10,当push时候会先判断是否需要扩大数组容量。pop()时候会先取出数据,之后再删除。

public class ArrayStack {//存储元素的数组,声明为Object类型能存储任意类型的数据private Object[] elementData;//指向栈顶的指针private int top;//栈的总容量private int size;//默认构造一个容量为10的栈public ArrayStack(){this.elementData = new Object[10];this.top = -1;this.size = 10;}public ArrayStack(int initialCapacity){if(initialCapacity < 0){throw new IllegalArgumentException("栈初始容量不能小于0: "+initialCapacity);}this.elementData = new Object[initialCapacity];this.top = -1;this.size = initialCapacity;}//压入元素public Object push(Object item){//是否需要扩容isGrow(top+1);elementData[++top] = item;return item;}//弹出栈顶元素public Object pop(){Object obj = peek();remove(top);return obj;}//获取栈顶元素public Object peek(){if(top == -1){throw new EmptyStackException();}return elementData[top];}//判断栈是否为空public boolean isEmpty(){return (top == -1);}//删除栈顶元素public void remove(int top){//栈顶元素置为nullelementData[top] = null;this.top--;}/*** 是否需要扩容,如果需要,则扩大一倍并返回true,不需要则返回false* @param minCapacity* @return*/public boolean isGrow(int minCapacity){int oldCapacity = size;//如果当前元素压入栈之后总容量大于前面定义的容量,则需要扩容if(minCapacity >= oldCapacity){//定义扩大之后栈的总容量int newCapacity = 0;//栈容量扩大两倍(左移一位)看是否超过int类型所表示的最大范围if((oldCapacity<<1) - Integer.MAX_VALUE >0){newCapacity = Integer.MAX_VALUE;}else{newCapacity = (oldCapacity<<1);//左移一位,相当于*2}this.size = newCapacity;int[] newArray = new int[size];elementData = Arrays.copyOf(elementData, size);return true;}else{return false;}}}复制代码

1.3 应用--解析运算符

运算表4+3 * 2 如何运算?
机器从左到右的读取数据,第一次读到+运算符时候,继续读下一个数据,判断是否有优先级比+高,当读到*到最后时候,的优先级最高,这时候两边操作数先计算出结果。表达式变为4+6 ,又开始从左到右开始读。 从中我们能发现,当公式长的时候,这种方法就会变得非常慢了。 之所以会变得这么慢,主要还是我们写的公式机器读不懂,这样我们就把问题引导到了数据的存储问题上了,关于表达式我们定义了三种类型,以4+3 - 2为例子
前缀表达式:操作符在操作数前面 比如:+ - 432
中缀表达式:操作符在操作数中间,也就是4+3 -2
后缀表达式:操作符在操作数之后 ,比如: 4 3 +2-
相比较中缀表达式,前缀表达式和后缀表达式,两个比较容易读取,那么接下来只要将中缀表达式转换为后缀表达式或者是前缀表达式,问题就可以解决了。本文以后缀表达式为例子:



以中缀表达式4+3 * 2转换为后缀表达式为例:

当前扫描的元素 a2(栈顶->低) a1(栈顶->低) 说明
4 4 遇到操作数直接结果a2中
+ 4 + a1为空的,直接进入
3 4,3 + 遇到操作数直接进入a2中
* 4,3 +,* a1中栈顶+遇到优先级高的*自动加入
2 4,3,2 +,* 遇到操作数直接放到a2中
结束 4 3 2 * + 最后将a1中栈顶依次弹入a2中

此时我们得到了后缀表达式43 2 * +,机器读取的后缀表达式规则:

后缀表达式计算机求值
1、从左向有扫描
2、遇到数字,压入栈中
3、遇到运算符,弹出栈的两个数,并用运算符对这两个数相应计算,并将结构入栈
4、重复上述2、3步骤,知道表达式的最右端,最后的值即为表达式的结果

1.4 应用--深度优于搜索算法(DFS)

其实在图数据结构的深度优于搜索算法本质就是应用栈实现的, 深度优先搜索算法有如下规则:

  规则1:如果可能,访问一个邻接的未访问顶点,标记它,并将它放入栈中。

  规则2:当不能执行规则 1 时,如果栈不为空,就从栈中弹出一个顶点。

  规则3:如果不能执行规则 1 和规则 2 时,就完成了整个搜索过程。

基于上述图,应用栈来说明:
首先从1节点开始,查找2节点,此时第2节点比邻是3,5,将2弹入栈顶。选中第3节点,此时栈是[1,2,3] ,但是第3节点没有比邻了,那么将3弹出栈顶,回到了第2节点,因为第3节点已经被选过了,选中第5节点,此时栈是[1,2,5]...,依照规则,最后栈的结果[1,2,3,4,6,8,9]

转载于:https://juejin.im/post/5cc2ad88f265da038c021a31

stack(栈)数据结构详解相关推荐

  1. Java Stack栈类详解

    栈是Vector的一个子类,它实现了一个标准的后进先出的栈. 堆栈只定义了默认构造函数,用来创建一个空栈. 堆栈除了包括由Vector定义的所有方法,也定义了自己的一些方法. Stack() 除了由V ...

  2. java语言链栈_Java语言实现数据结构栈代码详解

    近来复习数据结构,自己动手实现了栈.栈是一种限制插入和删除只能在一个位置上的表.最基本的操作是进栈和出栈,因此,又被叫作"先进后出"表. 首先了解下栈的概念: 栈是限定仅在表头进行 ...

  3. 万字长文的Redis五种数据结构详解(理论+实战),建议收藏。

    本文脑图 前言 Redis是基于c语言编写的开源非关系型内存数据库,可以用作数据库.缓存.消息中间件,这么优秀的东西一定要一点一点的吃透它. 关于Redis的文章之前也写过三篇,阅读量和读者的反映都还 ...

  4. redis数据结构详解之Hash(四)

    原文:redis数据结构详解之Hash(四) 序言 Hash数据结构累似c#中的dictionary,大家对数组应该比较了解,数组是通过索引快速定位到指定元素的,无论是访问数组的第一个元素还是最后一个 ...

  5. Python中的高级数据结构详解

    这篇文章主要介绍了Python中的高级数据结构详解,本文讲解了Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint这些数据结构的用法,需要的朋友可以参考 ...

  6. [转]Redis内部数据结构详解-sds

    本文是<Redis内部数据结构详解>系列的第二篇,讲述Redis中使用最多的一个基础数据结构:sds. 不管在哪门编程语言当中,字符串都几乎是使用最多的数据结构.sds正是在Redis中被 ...

  7. Redis数据结构详解之Zset(五)

    原文:Redis数据结构详解之Zset(五) 序言 Zset跟Set之间可以有并集运算,因为他们存储的数据字符串集合,不能有一样的成员出现在一个zset中,但是为什么有了set还要有zset呢?zse ...

  8. 【肝帝一周总结:全网最全最细】☀️Mysql 索引数据结构详解与索引优化☀️《❤️记得收藏❤️》

    [肝帝一周总结:全网最全最细]☀️Mysql 索引数据结构详解与索引优化☀️<❤️记得收藏❤️> 目录

  9. [redis] 10 种数据结构详解

    [redis] 10 种数据结构详解 简介 5种常见数据结构 string: 最常见的 string key value list: 双向链表 set: 集合- zset: 有序集合 hash: 类似 ...

  10. 数据结构详解——最大(小)左倾树

    数据结构详解--最大(小)左倾树 文章目录 数据结构详解--最大(小)左倾树 最大(小)左倾树的定义及用途 操作最大HBLT 合并操作 插入操作和删除操作 初始化操作 Java语言实现的最大HBLT ...

最新文章

  1. 重载[] int operator[ ]( )
  2. PMCAFF|百度客户端产品:高效开发客户端产品的正确姿势
  3. Hive分区、分桶操作及其比较(转自:http://blog.csdn.net/epitomizelu/article/details/41911657)
  4. java宠物店多态源代码
  5. 实验5: IOS的升级与恢复
  6. 布局—column(属性)
  7. 学会Git玩转Github笔记(一)——Github基本概念 仓库管理
  8. Typora的图片根目录设置,
  9. idea常用快捷方式
  10. C# Select SelectMany 区别
  11. 挖金矿 详解(C++)
  12. 编程计算二叉树中某结点的层数
  13. DOS命令打开一个软件,以及在python中的使用
  14. 微信电脑多开,骚操作走起
  15. 计算机散热 测试,散热拷机实测_笔记本评测-中关村在线
  16. 学习Java的心路历程
  17. Excel的最大行数
  18. SQLite+python
  19. Word打字很卡顿 Office打字时反应慢 延迟 Excel输入迟钝 PPT卡死的终极解决办法大全(24种方法)
  20. 单应用下RabbitMQ如何保证线程安全,及多应用下抢数据问题

热门文章

  1. Mybatis-实现逆向代理
  2. python学习笔记第六节(函数,装饰器)
  3. 【物联网智能网关-16】成功移植SQLite(STM32 .NET MF平台)
  4. Tensorflow-slim 学习笔记(一)概述
  5. [禅悟人生]不自律的品性如堕落的瓷瓶
  6. Windows7中安装内存与可用内存不一致的解决办法
  7. 我是如何战胜懒惰的?
  8. 深入理解Java堆内存分配策略(Xmx和Xms)
  9. PHP书写规范 PHP Coding Standard
  10. ElasticSearch High Level REST API【3】Scroll 滚屏