栈(英语:stack)又称为栈或堆叠,是计算机科学中一种特殊的串列形式的抽象数据类型,其特殊之处在于只能允许在链表或数组的一端(称为堆栈顶端指针,英语:top)进行加入数据(英语:push)和输出数据(英语:pop)的运算。另外栈也可以用一维数组或链表的形式来完成。堆栈的另外一个相对的操作方式称为队列。

由于堆栈数据结构只允许在一端进行操作,因而按照后进先出(LIFO, Last In First Out)的原理运作。

其基本的结构,如下图:

操作模型简图

参考了一篇BLOG,借用其中的图片,可以很清晰的看到其模型(侵立删):

抽象方法模型

  • 初始化 init: -> Stack
  • 出栈 push: N x Stack -> Stack
  • 获取栈顶元素,不出栈 peek: Stack -> (N U ERROR)
  • 出栈 pop: Stack -> Stack
  • 是空栈 isempty: Stack -> Boolean

JAVA接口定义



public interface StackInterface<T> {

  /**
* 出栈
*
* @return
*/
T pop(); /**
* 进栈
*
* @param t
*/
void push(T t); /**
* 获取栈顶元素,未出栈
*
* @return
*/
T peek(); /**
* 检查是否为空栈
*
* @return
*/
boolean isEmpty(); /** 清空栈 */
void clear(); /**
* 当前栈深度
*
* @return
*/
int length();
}

栈的实现代码

package com.tao.struct.stack;

public class BaseStack<T> implements StackInterface<T> {

  // 默认栈的空间长度
private final int DEFAULT_STACK_SIZE = 8; // 当前栈的指向
private int top = -1; T[] objects = null; public BaseStack() {
//JAVA 不支持泛型数组,只能这么做了 :):grimacing:
objects = (T[]) new Object[DEFAULT_STACK_SIZE];
} @Override
public T pop() {
if (isEmpty()) {
return null;
}
T t = objects[top--];
return t;
} @Override
public void push(T t) {
if (top >= DEFAULT_STACK_SIZE - 1) {
throw new IllegalStateException("栈已满,无法进栈,最大深度 " + DEFAULT_STACK_SIZE);
}
objects[++top] = t;
} @Override
public T peek() {
if (isEmpty()) {
return null;
}
T object = objects[top];
return object;
} @Override
public boolean isEmpty() {
return top == -1;
} @Override
public void clear() {
objects = (T[]) new Object[DEFAULT_STACK_SIZE];
top = -1;
} @Override
public int length() {
return top;
}
}

测试代码

为了实现创建的栈的测试,我们这里写了一个简单POJO对象,作为测试使用,也可以自己尝试创建一个对象


class Person { private String name; private int age; public Person() {} public Person(String name, int age) {
this.name = name;
this.age = age;
} @Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}

创建一个栈对象,使用其方法测试


public class TestBaseStack { public static void main(String[] args) {
BaseStack<Person> stack = new BaseStack<>();
System.out.println("--------------------------循环新增测试--------------------------");
for (int i = 0; i < 8; i++) {
Person person = new Person("姓名:" + i, i);
stack.push(person);
}
System.out.println("新增栈元素完成 当前栈深度 = " +stack.length()); System.out.println("--------------------------测试满栈--------------------------");
try {
stack.push(new Person("测试", 0));
} catch (IllegalStateException ex) {
System.out.println(ex.getMessage());
} System.out.println("--------------------------循环测试出栈--------------------------");
while (stack.peek() != null) {
// 获取栈顶元素出栈
System.out.println("出栈元素为 ------>" + stack.pop());
}
// 新增栈元素
System.out.println("--------------------------新增栈元素测试--------------------------");
stack.push(new Person("测试账户",12));
// 显示入栈元素
System.out.println("栈顶元素为 ------>" + stack.peek()); System.out.println("--------------------------清空栈测试--------------------------");
System.out.println("当前栈是否为空 ------> " + stack.isEmpty());
stack.clear();
System.out.println("当前栈是否为空 ------> " + stack.isEmpty()); }
}

测试效果

可以看到实现了基本的栈的功能,后期我们将尝试使用Stack的应用场景.


--------------------------循环新增测试--------------------------
新增栈元素完成 当前栈深度 = 7
--------------------------测试满栈--------------------------
栈已满,无法进栈,最大深度 8
--------------------------循环测试出栈--------------------------
出栈元素为 ------>Person{name='姓名:7', age=7}
出栈元素为 ------>Person{name='姓名:6', age=6}
出栈元素为 ------>Person{name='姓名:5', age=5}
出栈元素为 ------>Person{name='姓名:4', age=4}
出栈元素为 ------>Person{name='姓名:3', age=3}
出栈元素为 ------>Person{name='姓名:2', age=2}
出栈元素为 ------>Person{name='姓名:1', age=1}
出栈元素为 ------>Person{name='姓名:0', age=0}
--------------------------新增栈元素测试--------------------------
栈顶元素为 ------>Person{name='测试账户', age=12}
--------------------------清空栈测试--------------------------
当前栈是否为空 ------> false
当前栈是否为空 ------> true

Java实现栈数据结构的更多相关文章

  1. java 16 - 5 LinkedList模拟栈数据结构的集合

    请用LinkedList模拟栈数据结构的集合,并测试 题目的意思是: 你自己的定义一个集合类,在这个集合类内部可以使用LinkedList模拟. package cn_LinkedList; impo ...

  2. Java基础知识强化之集合框架笔记29:使用LinkedList实现栈数据结构的集合代码(面试题)

    1. 请用LinkedList模拟栈数据结构的集合,并测试:  题目的意思是:     你自己的定义一个集合类,在这个集合类内部可以使用LinkedList模拟,使用LinkedList功能方法封装成 ...

  3. 深入理解Java 栈数据结构

    栈(stack)又名堆栈,它是一种运算受限的线性表.其限制是仅允许在表的一端进行插入和删除运算.这一端被称为栈顶,相对地,把另一端称为栈底.向一个栈插入新元素又称作进栈.入栈或压栈,它是把新元素放到栈 ...

  4. [转]详细介绍java中的数据结构

    详细介绍java中的数据结构 本文介绍的是java中的数据结构,本文试图通过简单的描述,向读者阐述各个类的作用以及如何正确使用这些类.一起来看本文吧! 也许你已经熟练使用了java.util包里面的各 ...

  5. 详细介绍java中的数据结构

    详细介绍java中的数据结构 http://developer.51cto.com/art/201107/273003.htm 本文介绍的是java中的数据结构,本文试图通过简单的描述,向读者阐述各个 ...

  6. Java虚拟机栈和本地方法栈

    Java虚拟机栈的特征 线程私有 后进先出(LIFO)栈 存储栈帧,支持Java方法的调用.执行和退出 可能出现OutOfMemoryError异常和StackOverflowError异常 Java ...

  7. 20172328 2018-2019《Java软件结构与数据结构》第一周学习总结

    20172328 2018-2019<Java软件结构与数据结构>第一周学习总结 概述 Generalization 本周学习了软件质量.数据结构以及算法分析的具体内容,主要依托于所用教材 ...

  8. 20172328 2018—2019《Java软件结构与数据结构》第二周学习总结

    20172328 2018-2019<Java软件结构与数据结构>第二周学习总结 概述 Generalization 本周学习了第三章集合概述--栈和第四章链式结构--栈.主要讨论了集合以 ...

  9. 20172328 2018-2019《Java软件结构与数据结构》第三周学习总结

    20172328 2018-2019<Java软件结构与数据结构>第三周学习总结 概述 Generalization 本周学习了第五章:队列.主要内容包含队列的处理过程.如何用对例如求解问 ...

随机推荐

  1. HashMap和HashTable简介和区别

    一.HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长. HashMap是非线程安全的, ...

  2. [Swift]LeetCode323. 无向图中的连通区域的个数 $ Number of Connected Components in an Undirected Graph

    Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...

  3. PHP算法之冒泡排序

    //冒泡排序 //①思路,先比较出第一次,找一个最大的值,排到最后; //②重复count遍之后,就能得到排序; //③优化,每一次循环之后不需要再次全部重复; $array = [11,5,4,58 ...

  4. maven的安装与配置(本地仓库、阿里云镜像设置)

    参考一:https://www.cnblogs.com/sigm/p/6035155.html 参考二:https://blog.csdn.net/AmaniZ/article/details/792 ...

  5. Import Excel void (NPOI)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  6. JAVA实现在线查看PDF和office文档

    一个项目中要做一个在线预览附件(和百度文库差不多)的小功能点,楼主在开发过程中踩了很多坑的同时也总结了一些方法,仅供广大猿友参考,那么要实现这个小功能,目前主要是有如下3种可行的实现方式,下面先说实现 ...

  7. python:pip命令使用

    pip命令安装库  pip install 库名 使用pip命令更新库 pip install --upgrade 库名 比如更新scikit-learn包 pip install --upgrade ...

  8. Linux~上部署.net MVC出现的问题与解决

    这几天一直在搞linux下面的.net mvc的部署工作,遇到了很多问题,还好有一些朋友的帮助,问题才得到了解决! 环境:Linux+Mono+Jexus 希望的结果:直接运行windows+vist ...

  9. Python进阶:自定义对象实现切片功能

    2018-12-31 更新声明:切片系列文章本是分三篇写成,现已合并成一篇.合并后,修正了一些严重的错误(如自定义序列切片的部分),还对行文结构与章节衔接做了大量改动.原系列的单篇就不删除了,毕竟也是 ...

  10. Asp.Net SignalR GlobalHost外部通知

    GlobalHost 外部通知 之前都是在集线器类中进行服务器对客户端的通知操作,但是在开发中往往会有需求监控某个系统 ,比如OA系统  上级领导在上面宣布下午两点要开会 那么就要通知到其他的人.这里 ...