数据结构九——栈

文章出处:极客时间《数据结构和算法之美》-作者:王争。该系列文章是本人的学习笔记。

1栈的定义

1.1 栈的定义

栈:后进者先出,先进着后出。就像一碟盘子,如果拿走一个盘子,拿走的一定是最后放上去的那个。栈是一种操作受限的线性表,只允许在一端插入和删除。本质上来说就是一个操作不方便的数组或者链表。

栈存在的意义是什么?数据结构本身就是对特定场景的抽象,要求操作不多不少,正好满足场景需求。过多的接口会带来操作不可控,进而操作结果不可预计。

1.2 实现栈

我们可以使用数组实现一个栈,称为顺序栈;也可以用链表实现一个栈,称为链式栈。

/*** 数组实现的栈,在一端插入和删除,那就对数组的最后一个元素操作吧*/
public class ArrayStack {//存储数据的值private int[] items;//容量private int n;//存储元素个数private int size;/**** @param capacity*          容量*/public ArrayStack(int capacity){this.n = capacity;items = new int[n];}/*** 添加元素,如果还有空间则添加成功,返回true。否则返回false。* @param val* @return*/public boolean push(int val){if(this.size >=n) return false;items[size++] = val;return true;}/*** 栈内元素个数* @return*/public int size(){return this.size;}/*** 删除栈顶元素。如果当前栈内没有元素,则抛出异常。在调用pop之前先调用size()吧。* @return*/public int pop(){if(size==0) throw new IllegalArgumentException("栈目前没有任何元素,不能弹出元素");return items[--size];}
}

复杂度分析。push,pop时间复杂度为O(1),即使链表实现的栈也一样。空间复杂度式O(n)。需要大小为n的数组存储栈内元素。

1.3 支持动态扩容的栈

上面的实现中,当栈内没有空间的时候,就不能再插入元素。如果实现一个空间不受限的栈呢?这是一个数组自动扩容、自动减少空间的过程。我们只需要判断在数组满了的时候申请一个2倍容量的数组,将原有元素拷贝过去。

当栈内元素只有数组容量1/4的时候,将数组容量缩小到一半。当然对内存空间不敏感的应用可以不用做这一步。

	/*** 添加元素* @param val*/public void push(int val){if(this.size >=n) {grow();}items[size++] = val;}private void grow() {int newSize = 2*size;int[] newItmes = new int[newSize];System.arraycopy(this.items,0,newItmes,0,size);this.n = newItmes.length;this.items = newItmes;}

接下来我们分析一下支持动态扩容的栈入栈时间复杂度是多少。入栈操作的平均时间复杂度用摊还分析法。为了分析方便,我们先做以下假设:
1 只有扩容操作,扩容为原来数组2倍大小;
2 只有push,没有pop操作;
3 定义不涉及内存搬移的入栈操作为simple-push。

如果当前数组大小为K,当再有新的数据入栈的时候,需要申请一个大小为2K的数组,并且有K次数据迁移的操作。但是接下来的K-1次入栈操作,就无需申请内存和迁移数据。

如图所示,第K次入栈,需要的K次迁移操作,可以均摊到到未来K-1次入栈操作。所以这K次操作,平均下来每次是一次数据迁移和一个simple-push。时间复杂度O(1)。

2栈的应用

2.1 栈在函数调用中的应用

2.2 栈在表达式求值中的应用

2.3 栈在括号匹配中的应用

3 浏览器支持前进后退操作

浏览器前进、后退操作是这样的。当你访问页面 a->b->c之后,你可以按后退按钮回到页面b,再继续按前进按钮到页面c。

我们使用两个栈X、Y来完成浏览器的前进后退操作。当访问页面的时候,我们按照顺序将页面入栈X。当按后退按钮的时候,从X栈取出元素,入栈Y。当按前进按钮的时候,从Y栈取出元素,入栈X。当X栈为空的时候,后退按钮不能用。当Y栈为空的时候,前进按钮不能用。

例如初始:
X
Y

访问页面a:
X:a
Y

访问页面b:
X:a,b
Y
访问页面c:
X:a,b,c
Y

按后退按钮,展示页面b:
X:a,b
Y:c

按后退按钮,展示页面a:
X:a
Y:c,b

按前进按钮,从页面a到页面b:
X:a,b
Y:c

这个时候,你访问了新页面d,这时候前进按钮应该不能用,因为d的下一个页面还没有产生;按后退按钮的话应该回到b;所以c页面不能通过前进后退转到,需要清空Y栈:
X:a,b,d
Y:

4 思考

Java虚拟机中有堆栈的概念。栈内用来存储临时变量和方法调用,堆内存储Java对象。那么Java虚拟机中的栈和这里的栈,概念一样吗?
答:不一样。数据结构中的栈是对场景的抽象,是抽象的数据机构。
JVM使用的内存分为代码区、静态数据区和动态数据区。
代码区:存放方法的二进制代码,控制代码区代码执行切换。
静态数据区:全局变量、静态变量,常量(包含final修饰的和String)。
动态数据区:分为堆区和栈区。堆区存放对象,该对象的引用存放在栈区。栈区存放运行方法的形参、局部变量和返回值。

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

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

相关文章

java 传入多个参数时报Parameter 'XXX' not found. Available parameters are [arg1, arg0, param1,... 解决方案...

Select("SELECT id FROM ae_post ORDER BY id DESC LIMIT #{page},#{size}")List<Post> getAllForPage(Param("page") int page, Param("size")int size); dao层写入&#xff0c;解决方法如上 注&#xff1a;多参数需要添加 Param("…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第33篇]Bellcore攻击是如何攻击使用CRT的RSA的?

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 转载链接:https://www.cnblogs.com/zhuowangy2k/p/12245604.html

spring学习(14):Autowired的使用场景

CompactDisc类 package soundSystem;import org.springframework.stereotype.Component;Component public class CompactDisc {public CompactDisc() {super();System.out.println("compactdisc无参构造方法");}public void play(){System.out.println("正在播…

数据结构十——队列

文章出处&#xff1a;极客时间《数据结构和算法之美》-作者&#xff1a;王争。该系列文章是本人的学习笔记。 1 队列 队列&#xff1a;可以想象成排队买票&#xff0c;先来的人先买&#xff0c;后到的人站在队尾。先进者先出&#xff0c;这就是队列。 队列的操作&#xff1a…

[教程]博客园插入视频教程

【学习观15】人类为啥不进化成过目不忘&#xff1f;记忆力差难道不阻碍学习吗&#xff1f; 代码 <div class"video"> <iframe src"//player.bilibili.com/player.html?aid54874176&cid95969626&page1" scrolling"no" border&q…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第34篇]描述攻击离散对数问题的baby-step/Giant-step方法

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 Baby-step/Giant-step是Dnaiel Shanks为解决DLP问题开发的算法。DLP问题已经是许多现代密码学的困难性基础。…

spring学习(15):required属性

CompactDisc类 package soundSystem;import org.springframework.stereotype.Component; //注解Componentpublic class CompactDisc {public CompactDisc() {super();System.out.println("compactdisc无参构造方法");}public void play(){System.out.println("…

爬虫的单线程+多任务异步协程:asyncio 3.6

单线程多任务异步协程:asyncio 3.6 事件循环 无限循环的对象.事件循环中最终需要将一些 特殊的函数(被async关键字修饰的函数) 注册在该对象中.协程 本质上是一个对象.可以把协程对象(特殊的函数)注册到事件循环中任务对象 就是对协程对象进一步的封装.绑定回调: task.add_done…

算法十——深度优先搜索和广度优先搜索

文章出处&#xff1a;极客时间《数据结构和算法之美》-作者&#xff1a;王争。该系列文章是本人的学习笔记。 搜索算法 算法是作用于数据结构之上的。深度优先搜索、广度优先搜索是作用于图这种数据结构之上的。图上的搜索算法可以理解为从一个顶点到另外一个顶点。 常用的搜…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol 52][第35篇]给针对ECDLP问题的Pollard rho,parallel Pollard rho攻击的一个粗略的描述

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 [1] http://www.cs.bris.ac.uk/~nigel/Crypto_Book/book.ps (pages 208 - 214) 转载连接&#xff1a;https…

spring学习(16):使用接口

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

交易系统高并发下的幂等性设计原则

一、介绍 幂等性就是针对同一个请求&#xff0c;不管该请求被提交了多少次&#xff0c;该请求都将被视为同一个请求&#xff0c;服务端不应该将同一个请求进行多次处理&#xff0c;以确认处理逻辑的正确性&#xff0c;针对交易性系统幂等性的设计尤为重要&#xff0c;否则由于网…

工程中选择数据结构和算法的依据

1. 时间、空间复杂度不能和性能划等号 时间、空间复杂度不是时间执行和内存消耗的精确值。它们只是表示了随着数据量的增长&#xff0c;时间、空间的增长趋势。 代码的执行时间有时不跟时间复杂度成正比。我们常说算法是O(nlogn),O(n2n^2n2)这些都是基于大数据量&#xff08;…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第36篇]Index Calculus算法

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 我们这篇博客继续描述一种数学攻击&#xff0c;这种数学攻击被叫做Index Calculus(IC)算法。 注意这里Index…

DS博客作业07--查找

1.本周学习总结 1.思维导图 2.谈谈你对树结构的认识及学习体会。 查找是一种跟我们生活息息相关的算法&#xff0c;最典型的例子就是搜索引擎&#xff0c;而评价一种查找算法的优劣的关键就是查找速度&#xff0c;生活中我们往往要在大量数据查找自己所需要的东西&#xff0c;如…

easyUI学习笔记二

1&#xff0e; 拖拉大小 <!DOCTYPE html> <html> <head><title>easyui学习</title><script type"text/javascript" src jquery-easyui/jquery.min.js> </script><script type"text/javascript" src jquer…

C语言—每日选择题—Day62

隔一天更新解析 第一题 1. 在使用标准C库时&#xff0c;下面哪个选项使用只读模式打开文件&#xff1f; A&#xff1a;fopen("foo.txt", "r") B&#xff1a;fopen("foo.txt", "r") C&#xff1a;fopen("foo.txt", "w&…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第37篇]The Number Field Sieve

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 转载链接&#xff1a;https://www.cnblogs.com/zhuowangy2k/p/12245636.html

大二下学期软件工程概论总结

软件工程概论这门课可以算是我本学期最辛苦的一门课了。但与此同时这门课给我带来的收获和其他课程相比&#xff0c;也不是一个量级的。 这学期我通过课上的学习与作业项目的完成过程&#xff0c;了解到软件开发由项目的确定到项目的需求分析&#xff0c;再到概要&#xff0c;详…

70. Climbing Stairs

输入&#xff1a;台阶数量n 输出&#xff1a;有多少种走法 规则&#xff1a;每次可以上一个台阶或者两个台阶 分析&#xff1a;想明白一件事情。如果现在在第k个台阶&#xff0c;那下一步可以到达第k1个台阶&#xff0c;或者第k2个台阶。换句话说想要到达第k个台阶&#xff0c;…