栈的定义

栈是限制在表的一段进行插入和删除的运算的线性表,通常能够将插入、删除的一端为栈顶,例外一端称为栈底,当表中没有任何元素的时候称为空栈。

通常删除(又称“退栈”)叫做弹出pop操作,每次删除的都是栈顶最新的元素;每次插入(又称“进栈”)称为压入push操作。

当栈满的时候,进行push 操作,会上溢,当空栈的时候进行退栈操作的时称为下溢。

上溢是一种出错的情况,下溢可能是正常的情况处理。

堆栈的运算是按照后进先出的原则,简称LIFO。

栈的基本运算定义:

initStack:构造一个空栈;

stackEmpty:判断是否为空;

stackFUll:判断是否栈满;

push:进栈,将该元素压入栈顶;

pop:退栈,弹出栈顶元素,注意非空判断;

stackTop:去除栈顶元素,不改变指针。

做个简单的Stack接口:

package com.wuwii.utils;

/**

* 堆栈

* @author Zhang Kai

* @version 1.0

* @since

2017/12/14 22:51

*/

public interface Stack {

/**

* 进栈

*

* @param element 进栈的元素

*/

void push(E element);

/**

* 弹出栈顶元素 ,并改变指针

*

* @return 栈顶元素

*/

E pop();

/**

* 返回栈顶元素 ,不改变指针

*

* @return 栈顶元素

*/

E topElement();

/**

* 判断是否为空栈

*

* @return true为空栈

*/

Boolean isEmpty();

/**

* 清空栈

*/

void clear();

}

顺序栈

就是符合LIFO运算规则的顺序线性表。

package com.wuwii.utils;

/**

* 顺序栈

* @author Zhang Kai

* @version 1.0

* @since

2017/12/14 23:05

*/

public class ArrayStack implements Stack {

/**

* 初始化栈的默认大小

*/

private final int defaultSize = 10;

/**

* 栈的集合大小

*/

private int size;

/**

* 栈顶的位置

*/

private int top;

/**

* 元素存储在数组

*/

private Object[] elements;

/**

* 初始化默认大小为10 的栈

*/

public ArrayStack() {

initStack(defaultSize);

}

/**

* 初始化指定大小的栈

* @param givenSize 指定栈大小

*/

public ArrayStack(Integer givenSize) {

initStack(givenSize);

}

/**

* 初始化栈

* @param givenSize 给定的栈大小

*/

private void initStack(Integer givenSize) {

size = givenSize;

top = 0;

elements = new Object[size];

}

/**

* 清空栈

*/

@Override

public void clear() {

top = 0;

}

/**

* 进栈

* @param element 进栈的元素

*/

@Override

public void push(E element) {

sizeCheckForPush();

elements[top++] = element;

}

/**

* 弹出栈顶元素 ,并改变指针

* @return 栈顶元素

*/

@Override

public E pop() {

sizeCheckForPop();

return (E) elements[--top];

}

/**

* 返回栈顶元素 ,不改变指针

* @return 栈顶元素

*/

@Override

public E topElement() {

sizeCheckForPush();

return (E) elements[top - 1];

}

/**

* 判断是否为空栈

* @return true为空栈

*/

@Override

public Boolean isEmpty() {

return size == 0;

}

/**

* 在进栈的时候检查

*/

private void sizeCheckForPush() {

if (top >= size) {

throw new RuntimeException("Stack overflow");

}

}

/**

* 退栈检查

*/

private void sizeCheckForPop() {

if (isEmpty()) {

throw new RuntimeException("Stack is empty");

}

}

}

链式栈

符合LIFO运算规则的链式线性表。

package com.wuwii.utils;

/**

* @author Zhang Kai

* @version 1.0

* @since

2017/12/15 12:58

*/

public class LinkStack implements Stack {

/**

* 链式单元

*/

private Node top;

/**

* 初始化链式堆栈

*/

public LinkStack() {

initStack();

}

/**

* 初始化

*/

private void initStack() {

top = null;

}

/**

* 存储单元

*/

private static class Node {

E element;

Node next;

Node(E element, Node next) {

this.element = element;

this.next = next;

}

}

/**

* 进栈

*

* @param element 进栈的元素

*/

@Override

public void push(E element) {

top = new Node(element, top);

}

/**

* 弹出栈顶元素 ,并改变指针

*

* @return 栈顶元素

*/

@Override

public E pop() {

checkEmpty();

E element = top.element;

top = top.next;

return element;

}

/**

* 返回栈顶元素 ,不改变指针

*

* @return 栈顶元素

*/

@Override

public E topElement() {

checkEmpty();

return top.element;

}

/**

* 判断是否为空栈

*

* @return true为空栈

*/

@Override

public Boolean isEmpty() {

return top == null;

}

/**

* 清空栈

*/

@Override

public void clear() {

if (isEmpty()) {

return;

}

for (Node x = top; x != null; ) {

Node next = x.next;

x.element = null;

x.next = null;

x = next;

}

size = 0;

}

/**

* 检查链式堆栈是否为空,为空抛出异常

*/

private void checkEmpty() {

if (isEmpty()) {

throw new RuntimeException("LinkStack is empty");

}

}

}

首先push 修改新产生的链表节点的next 域并指向栈顶,然后设置top 指向新的链表节点,pop则相反。

顺序栈和链式栈的比较

实现链式栈和顺序栈的操作都是需要常数时间,时间复杂度为O(1),主要从空间和时间复杂度考虑。

顺序栈初始化的时候必须要给定指定大小,当堆栈不满的时候,会造成一部分的空间浪费,链式栈变长,相对节约空间,但是增加了指针域,额外加大了数据结构的开销。

当需要多个堆栈共享的时候,顺序存储中可以充分的利用顺序栈的单向延伸,将一个数组可以存在两个堆栈里,每个堆栈从各自的栈顶出发延伸,这样减少了空间的浪费。但只有两个为堆栈的空间有相反的需求的时候才能使用。就是最好一个堆栈只能增加,一个只能减少。如果,两个一起增加,可能造成堆栈的溢出。

如果在多个顺序堆栈共享空间,一个堆栈满了,其他可能没满,需要使用堆栈的LIFO 运算法则,将满的堆栈元素向左或者右进行平移操作,这样会造成大量的数据元素移动,使得时间的开销增大。

相对来说,使用两个堆栈共享一个空间是比较适宜的存储方式,但是也增加了堆栈溢出的危险。

由于链式存储结构的不连续性,什么时候需要,就什么时候去存储,不存在溢出的问题,但是增加了结构的开销,总体上来说浪费了空间,但是不需要堆栈共享,

java顺序栈和链栈_Java的顺序栈和链式栈相关推荐

  1. 在java的实现栈的插入数据_Java实现数据结构栈stack和队列Queue

    回顾JDK提供的集合类 容器(集合)框架如下: 集合类存放于java.util包中.集合类存放的都是对象的引用,而非对象本身. 集合类型主要有3种:set(集).list(列表)和map(映射). C ...

  2. java中顺式和链式_Java单链表顺序和链式实现(数据结构五)

    1.迭代器实现 package com.zhaochao; public interface Iterator { boolean hasNext(); E next(); boolean delet ...

  3. java利用栈求复杂表达式_java中的栈Stack的基本使用和应用(二) ——利用栈计算合法的算术表达,中缀表达式转后缀表达式...

    利用栈Stack计算合法的算术表达式 限定的算术表达式求值问题:包含 "+"."-"."*"."/" .正整数和圆括号的 ...

  4. java顺序表增删查改_Java实现顺序表的增删改查

    public class MyArrayList { private int[] array;   //代表的是存在数据的数组 //array.length代表的是数组的容量 private int ...

  5. 数据结构Java实现05----栈:顺序栈和链式堆栈

    一.堆栈的基本概念: 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...

  6. java实现顺序栈_Java实现顺序栈原理解析

    这篇文章主要介绍了java实现顺序栈原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 什么是栈 1.栈的英文是stack 2.栈是一个先入后出 ...

  7. java 顺序栈_Java实现顺序栈

    一.分析 栈是限定仅在表的一端进行插入或删除操作的线性表,对于栈来说,操作端称为栈顶,另一端则称为栈底,栈的修改是按照后进先出的原则进行的,因此又称为后进先出的线性表. 顺序栈是指利用顺序存储结构实现 ...

  8. java stack 从1.5开始?_java数据结构与算法之栈(Stack)设计与实现

    本篇是java数据结构与算法的第4篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 栈是一种用于存储数据的简单数据结构,有点类似链表或者顺序表(统称线性表),栈与线 ...

  9. 数据结构-顺序栈、链栈

    一.堆栈的基本概念: 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...

最新文章

  1. 我们的2009 梦想照进了现实
  2. c++ :MFC 如何遍历窗口同类型控件ID
  3. Centos下的apache2练习
  4. 故障error: failed to run Kubelet: failed to create kubelet: misconfiguration: kubelet cgroup driver: “
  5. 解决python调试模型时,多次重复加载数据集与模型,节约大量等待时间
  6. 以太坊上DeFi协议总锁仓量首次突破350亿美元
  7. xcode快捷键大全(转)
  8. Android UI学习之Dialog
  9. 【Spring学习笔记七】-Spring MVC基本配置和实例
  10. java swing tooltips_tooltips 提示
  11. VMware安装win10镜像
  12. 查询服务器时显示failbyOEM,java - 使用 Weblogic 12c,给出警告警告日志管理 BEA-170011 该服务器上的 LogBroadcaster 失败 - 堆栈内存溢出...
  13. 微信屏蔽网址解决办法 微信网址被屏蔽了红了照样打开
  14. c语言函数rewind作用,c语言中的rewind()是什么意思
  15. 《蔡康永情商课——为自己活一次》
  16. (三) u-boot 启动分析_第一阶段
  17. html5 自动失去焦点,js input失去焦点事件
  18. proteus电路仿真软件使用方法
  19. 机器学习算法平台alink_阿里正式开源通用算法平台Alink,“双11”将天猫推荐点击率提升4...
  20. MAC、IP、ARP协议

热门文章

  1. 因此,甲骨文杀死了java.net
  2. 使用Speedment和Spring创建REST API
  3. 生产Java应用程序中的十大异常类型-基于1B事件
  4. 使用Java创建DynamoDB表
  5. Spring注释,我从来没有机会使用第1部分:@primary
  6. 为AWT的机器人创建DSL
  7. 在OpenShift上托管的WildFly实例上进行Arquillian测试
  8. 使用ActiveMQ –具有故障转移协议的“主/从”配置
  9. 最受欢迎的Java环境
  10. Spring MVC定制用户登录注销实现示例