数据结构与算法系列六(栈)
有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀!
有人说,我是做业务开发的,只要熟练API,熟练框架,熟练各种中间件,写的代码不也能“飞”起来吗?
于是问题来了:为什么还要学习数据结构与算法呢?
#理由一:
面试的时候,千万不要被数据结构与算法拖了后腿
#理由二:
你真的愿意做一辈子CRUD Boy吗
#理由三:
不想写出开源框架,中间件的工程师,不是好厨子
我想好了,还是需要学习数据结构与算法。但是我有两个困惑:
1.如何着手学习呢?
2.有哪些内容要学习呢?
学习方法推荐:
#学习方法
1.从基础开始,系统化学习
2.多动手,每一种数据结构与算法,都自己用代码实现出来
3.思路更重要:理解实现思想,不要背代码
4.与日常开发结合,对应应用场景
学习内容推荐:
数据结构与算法内容比较多,我们本着实用原则,学习经典的、常用的数据结构、与常用算法
#学习内容:
1.数据结构的定义
2.算法的定义
3.复杂度分析
4.常用数据结构
数组、链表、栈、队列
散列表、二叉树、堆
跳表、图
5.常用算法
递归、排序、二分查找
搜索、哈希、贪心、分治
动态规划、字符串匹配
你还记得在数组那一篇中,我们说过基于线性表的数据结构有哪些吗?它们是:数组、链表、栈、队列。
前面我们详细了解了数组和链表,数组和链表是很多数据结构和算法的基础数据结构。比如我们今天要学习的栈,就可以通过数组实现:顺序栈;也可以通过链表实现:链式栈。
那么问题来了:栈到底是什么样的数据结构呢?
#考考你:
1.你能用自己的话描述栈吗?
2.你知道栈都有哪些常见的应用场景吗?
package com.anan.struct.linetable; /** * 顺序栈:基于数组实现 * @param <E> */ public class ArrayStack<E> { private Object[] items; private int count;// 计数器(统计栈内元素个数) private int n;// 栈大小 public ArrayStack(int capacity){ this.items = new Object[capacity]; this.count = 0; this.n = capacity; } /** * 入栈操作 */ public boolean push(E e ){ // 检查栈是否满 if(count == n){ return false; } // 将元素放入栈中 items[count ++] = e; return true; } /** * 出栈操作 */ public E pop(){ // 判断栈是否空 if(count == 0){ return null; } // 返回下标为count-1的元素,并且下标-1 E e = (E)items[count - 1]; count --; return e; } public int getCount() { return count; } public int getN() { return n; } }
测试代码:
package com.anan.struct.linetable; /** * 测试栈 */ public class ArrayStackTest { public static void main(String[] args) { // 创建栈对象 ArrayStack<Integer> stack = new ArrayStack<Integer>(10); // 入栈操作 System.out.println("1.入栈操作-----------------------------"); for (int i = 0; i < 5; i++) { stack.push(i); System.out.println("当前入栈元素:" + i); } System.out.println("出栈前栈中元素个数:" + stack.getCount()); System.out.println("2.出栈操作-----------------------------"); // 出栈操作 for (int i = 0; i < 5; i++) { System.out.println("当前出栈元素:" + stack.pop()); } System.out.println("出栈后栈中元素个数:" + stack.getCount()); } }
测试结果:
D:\02teach\01soft\jdk8\bin\java com.anan.struct.linetable.ArrayStackTest 1.入栈操作----------------------------- 当前入栈元素:0 当前入栈元素:1 当前入栈元素:2 当前入栈元素:3 当前入栈元素:4 出栈前栈中元素个数:5 2.出栈操作----------------------------- 当前出栈元素:4 当前出栈元素:3 当前出栈元素:2 当前出栈元素:1 当前出栈元素:0 出栈后栈中元素个数:0 Process finished with exit code 0
#考考你答案:
1.你能用自己的话描述栈吗?
1.1.栈是基于线性表的数据结构
1.2.栈一种操作受限的数据结构
1.3.栈满足后进先出的特点
1.4.栈只允许在栈顶插入元素、和删除元素
2.你知道栈都有哪些常见的应用场景吗?
2.1.方法调用
a.在jvm内存结构中,有线程共享的:方法区、堆
b.在jvm内存结构中,有线程私有的:程序计数器、本地方法栈、虚拟机栈
c.在虚拟机栈中,每个方法调用都被封装成:栈帧
d.栈帧内容包含:局部变量表、操作数栈、方法出口信息等
e.每个方法的调用过程,就是栈帧在虚拟机栈中入栈和出栈过程
2.2.表达式求值
a.假设有一个表达式:1+1024*1-1
b.计算机中,如何求解该表达式的值呢?
c.注意:当然不是人为口算
d.我们的目的是让计算机能够理解任意表达式
2.3.表达式求值过程
a.用两个栈实现表达式求值
b.一个用于存储数据:操作数栈
c.一个用于存储运算符:运算符栈
d.从左至右,读取表达式内容
e.如果是数据,入栈到操作数栈中
f.如果是运算符,入栈到运算符栈中
g.比较运算符的优先级
h.如果遇到高优先级的运算符,则将操作数栈的数据出栈
i.进行计算,把新的计算结果重新入栈到操作数栈
j.以此类推...直到处理完成整个表达式
jvm内存结构:
表达式求值过程:1+1024*1-1
我们唯一能够控制的是自己的脾气和努力