栈的定义

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

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

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

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

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

栈的基本运算定义:

  • initStack:构造一个空栈;
  • stackEmpty:判断是否为空;
  • stackFUll:判断是否栈满;
  • push:进栈,将该元素压入栈顶;
  • pop:退栈,弹出栈顶元素,注意非空判断;
  • stackTop:去除栈顶元素,不改变指针。

做个简单的Stack接口:

package com.wuwii.utils;

/**
* 堆栈
* @author Zhang Kai
* @version 1.0
* @since <pre>2017/12/14 22:51</pre>
*/
public interface Stack<E> {
/**
* 进栈
*
* @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 <pre>2017/12/14 23:05</pre>
*/
public class ArrayStack<E> implements Stack<E> {
/**
* 初始化栈的默认大小
*/
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 <pre>2017/12/15 12:58</pre>
*/
public class LinkStack<E> implements Stack<E> {
/**
* 链式单元
*/
private Node<E> top; /**
* 初始化链式堆栈
*/
public LinkStack() {
initStack();
} /**
* 初始化
*/
private void initStack() {
top = null;
} /**
* 存储单元
*/
private static class Node<E> {
E element;
Node<E> next;
Node(E element, Node<E> next) {
this.element = element;
this.next = next;
}
}
/**
* 进栈
*
* @param element 进栈的元素
*/
@Override
public void push(E element) {
top = new Node<E>(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<E> x = top; x != null; ) {
Node<E> 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的顺序栈和链式栈的更多相关文章

  1. 顺序栈和链式栈(C++实现)

    顺序栈,是一种基于数组的存储表示. 实现类代码如下: template<class T> class SeqStack{ T *element; int top; int maxSize; ...

  2. 数据结构——Java实现顺序栈

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

  3. java实现顺序栈

    public class MyStack{ Object[] data; int top; int maxSize; public MyStack(int maxSize) { this.maxSiz ...

  4. java实现顺序表、链表、栈 (x)->{持续更新}

    1.java实现节点 /** * 节点 * @luminous-xin * @param <T> */ public class Node<T> { T data; Node& ...

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

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

  6. [Java算法分析与设计]--顺序栈的实现

    在程序的世界,栈的应用是相当广泛的.其后进先出的特性,我们可以应用到诸如计算.遍历.代码格式校对等各个方面.但是你知道栈的底层是怎么实现的吗?现在跟随本篇文章我们来一睹它的庐山真面目吧. 首先我们先定 ...

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

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

  8. 使用JAVA数组实现顺序栈

    1,首先总结一下线性表(分为顺序表和链接表,[即顺序存储结构和链式存储结构的区别])和栈(顺序栈和链接栈)还有队列(顺序队列和链接队列)的JAVA类库中的实现: java.util.ArrayList ...

  9. java 实现简单的顺序栈

    package com.my; import java.util.Arrays; /** * 顺序栈 * @author wanjn * */ public class ArrayStack { pr ...

随机推荐

  1. alibaba/canal 阿里巴巴 mysql 数据库 binlog 增量订阅&消费组件

    基于日志增量订阅&消费支持的业务: 数据库镜像 数据库实时备份 多级索引 (卖家和买家各自分库索引) search build 业务cache刷新 价格变化等重要业务消息 项目介绍 名称:ca ...

  2. HTML6的10个高级新特性

    网络技术正趋向于发展为一个巨大的移动APP市场,在Web开发的革命浪潮中起着指示性作用,自HTML引入以来,应用程序变得So easy,web开发中运用先进技术也很容易处理各种复杂Bug. 作为专业的 ...

  3. ios有些机型input和fixed导致的页面错位问题

    _fixIosInputH () { let [timeout, beforeTop] = [null, 0] $('input, textarea').on('focus', () => { ...

  4. ats 转发代理

    ats是一个通用代理,可配置为反向和转发代理; 转发代理可以用作基础架构中的中央工具来访问web, 它可以与缓存结合使用以降低 总体带宽使用率.转发代理充当本地网络上的客户端浏览器与这些客户端访问的所 ...

  5. Codeforces Round #515 (Div. 3) 解题报告(A~E)

    题目链接:http://codeforces.com/contest/1066 1066 A. Vova and Train 题意:Vova想坐火车从1点到L点,在路上v的整数倍的点上分布着灯笼,而在 ...

  6. 10款常见MySQL高可用方案选型解读

    一.概述 我们在考虑MySQL数据库的高可用架构时,主要考虑如下几方面: 如果数据库发生了宕机或者意外中断等故障,能尽快恢复数据库的可用性,尽可能的减少停机时间,保证业务不会因为数据库的故障而中断. ...

  7. Scrum Meeting 10.27

    1.会议内容: 姓名 今日任务 明日任务 预估时间(h) 徐越 配置SQLserver 学习本地和服务器之间的通信 4 卞忠昊 找上届代码的bug 学习安卓布局(layout)的有关知识,研究上届学长 ...

  8. java 实验1

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计 班级:1352 姓名:杨光 学号:20135233 成绩:            指导教师:娄嘉鹏  实验 ...

  9. web09 struts2配置 struts2入门

    电影网站:www.aikan66.com 项目网站:www.aikan66.com游戏网站:www.aikan66.com图片网站:www.aikan66.com书籍网站:www.aikan66.co ...

  10. 软件项目第一次Sprint评价

    1.9-652 首先该小组在第一个冲刺阶段的目标还是很明确的,按照这个目标去完成并实现任务,最后也确实是实现了.通过展示目前已经完成了界面的设计及实现.初步的游戏人物设定.生命值设定.除了完成的这些, ...