数据结构(5)--栈
来源:互联网 发布:爱剪辑mac能用吗 编辑:程序博客网 时间:2024/05/16 07:43
相信大家平时在码代码的时候会经常出现StackOverflowError,这个错误就是栈溢出的错误了.而栈溢出经常是因为方法运行的时候,请求新建栈帧时
栈所剩空间小于战帧所需空间。
实例:在递归调用方法,不停产生栈帧,导致栈空间异常,抛出错误.(这时候我们应该要注意到我们递归出口否是定义了)
还有一点小知识进行拓展:
栈是一个线程私有的,通常用于保存方法(函数)中的参数,局部变量。在java中,所有基本类型和引用类型的引用都在栈中存储。栈中数据的生存空间一般在当前scopes内(就是由{…}括起来的区域)
但是,我们今天的重点不是这个.我们的重点是栈.我们接下来就认识一下栈,这么一个东西.
堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除操作。
先进后出:堆栈中允许进行插入和删除操作的一端称为栈顶,另一端称为栈底。堆栈的插入和删除操作通常称为进栈或入栈,堆栈的删除操作通常称为出栈或退栈。(注意:这个是最大的特点:经常考试考研都会出到的)
还有以下这么几个概念:
栈:限定只在表尾进行插入和删除操作的线性表。
栈是线性表:其特殊性在于插入和删除操作必须在表尾。
空栈:栈中没有数据元素。
压栈(进栈):往栈中输入数据元素。
弹栈(出栈):从栈中输出数据元素。
栈顶:允许进行数据插入删除操作的一端是栈。
栈底:不允许进行数据插入删除操作的一端是栈。
共享栈:指有两个相同类型的顺序栈,一个栈已经满载,另一个却仍有空闲时间,为了能充分利用到未被使用的空闲空间,可以采用共享栈。
由于栈是线性表的特例,而线性表我们是采用数组实现的,而我们也用数组模拟顺序栈.
代码实现:
/** * 思路: * 1. 利用数组初始化栈对象 * 2. 对栈进行安全性判断 * 3. 入栈出栈操作 * @author Administrator * * @param <T> */ public class LinearStack<T> { //初始栈的数据 private T[] data; private int size; private int top=-1; //建长度为5的空栈 LinearStack() { this(null); } //建长度为5,栈顶为element的栈 LinearStack(T element) { this(element,5); } //1.初始化栈,自定义大小和参数对象传入 public LinearStack(T element, int size) { if(size <= 0) { return; } data = (T[]) new Object[size]; this.size = size; if(element != null) { data[0] = element; top++; } } //获取长度 public int getlength(){ if(top==-1){ return 0; }else{ return top+1; } } //判断是否为空 public boolean isEmpty(){ return top==-1; } public boolean isFull(){ return top==size-1; } //压栈 /** * 思路: * 1. 先++拓展出一个空位 * 2. 然后再赋值 * @param element * @return */ public boolean Push(T element) { if(isFull()) return false; top++; data[top] = element; return true; } //弹栈 public T Pop() { if(isEmpty()) return null; T temp = data[top]; top--; return temp; } //重写父类toString方法,做栈顶到栈底的遍历 public String toString() { int len = getlength(); if(len == 0) { return "[ ]"; }else{ //字符串拼接 StringBuffer sb = new StringBuffer(); sb.append("[ "); for(int i = 0; i < len; i++) { sb.append(data[i]+" "); } sb.append("]"); return sb.toString(); } } public static void main(String[] args) { LinearStack<String> linearStack = new LinearStack<>("1"); //去掉初始化那个吧 linearStack.Pop(); linearStack.Push("A"); linearStack.Push("B"); linearStack.Push("C"); linearStack.Push("D"); linearStack.Push("E"); System.out.println(linearStack.getlength()); linearStack.Pop(); linearStack.Pop(); System.out.println(linearStack.getlength()); } }
当然我们还有一个是链式栈,但是实际应用中,我们更多是讨论的顺序栈,对于链式栈,就是用链式表表达栈,每一个位置用一个结点表示.大家可以到时候google一下相关的.
两者优劣势:
顺序栈和链栈的插入、删除操作时间复杂度都是O(1);
顺序栈需要事先确定数组的长度,有可能存在浪费内存空间的情况;
链栈虽然不需要事先确定表长,但因为需要存储链式指针,同时加大了内存开销;
因此,如果数据元素变化不可预测,时大时小,最好使用链栈;如果它的变化空间在可控范围内,则可以考虑使用顺序栈。
- 数据结构(5)--栈
- 栈-数据结构(5)
- 数据结构5(链式栈)
- 数据结构---栈
- 数据结构-栈
- 数据结构 栈
- 数据结构--栈
- 数据结构 栈
- 数据结构(栈)
- 数据结构栈
- 数据结构-栈
- 数据结构-----栈
- 数据结构-栈
- 【数据结构】栈
- 数据结构---->栈
- 数据结构---栈
- 数据结构--栈
- 数据结构----栈
- Google MDL Badge - 徽章, 小红点?
- 如果看了这篇文章你还不懂傅里叶变换,那就过来掐死我吧
- 隐写术
- Java中Iterator(迭代器)的一般用法
- Android消息机制的原理剖析—闭环总结
- 数据结构(5)--栈
- Mysql无法创建外键的原因
- php 三维数组转成二维数组
- 数位dp学习
- Hibernate
- 使用surfaceview实现直播中的点赞效果
- 深入理解OC的继承与复合
- 数据结构(6)--逆波兰计算器的运用
- bootstrap 上传图片插件 file-input 的简单使用