栈定义

栈(stack):是一种特殊的串行形式的数据结构,其特殊之处在于只允许在链接串行或者阵列的

一端进行插入、删除操作。其实现方式可以通过一维阵列和链接串行来实现。

Tips:简单的来说栈其实也是一种操作受限的线性表。是一种后进先出的数据结构可以使用数

组或者链表的形式来实现。

栈的操作表现形式:

栈实现

知道了栈的定义,我们来看看栈的实现吧。首先我们需要明白的的是栈具有哪些操作。

通过一个接口定义其操作。

  1. package com.kiritor;
  2. /**
  3. * 栈操作定义
  4. * @author Kiritor*/
  5. public interface Stack<T> {
  6. /*判空*/
  7. boolean isEmpty();
  8. /*清空栈*/
  9. void clear();
  10. /*弹栈*/
  11. T pop();
  12. /*入栈*/
  13. boolean push(T data);
  14. /*栈的长度*/
  15. int length();
  16. /*查看栈顶的元素,但不移除它*/
  17. T peek();
  18. /*返回对象在栈中的位置*/
  19. int search(T t);
  20. }

栈的数组实现

栈的数组实现,底层使用数组

  1. package com.kiritor;
  2. /**
  3. * 栈的数组实现
  4. * @author Kiritor*/
  5. public class ArrayStack<T> implements Stack<T>{
  6. private T[] t = (T[]) new Object[16];//栈空间默认为16
  7. private int size = 0;
  8. @Override
  9. public boolean isEmpty() {
  10. return size==0;
  11. }
  12. @Override
  13. public void clear() {
  14. for(int i = 0;i<t.length;i++)
  15. t[i]=null;//将其引用只为null,方便gc进行回收
  16. size = 0;//栈的大小置0
  17. }
  18. /*弹栈操作*/
  19. @Override
  20. public T pop() {
  21. if(size==0)
  22. return null;
  23. else
  24. {
  25. T tmp = t[size-1];
  26. t[size-1]=null;//便于gc回收
  27. size--;
  28. return tmp;
  29. }
  30. }
  31. @Override
  32. public boolean push(T data) {
  33. if(size>=t.length)
  34. {
  35. //栈空间已满,需要扩容
  36. resize();
  37. }
  38. t[size++]=data;
  39. return true;
  40. }
  41. public void resize()
  42. {
  43. T[] tmp = (T[]) new Object[t.length*2];
  44. for(int i = 0;i<t.length;i++){
  45. tmp[i]=t[i];
  46. t[i]=null;//便于gc处理
  47. }
  48. t = tmp;
  49. tmp = null;//便于gc处理,提高程序效率
  50. }
  51. @Override
  52. public int length() {
  53. return size;
  54. }
  55. /*查看栈顶元素,但是并不删除*/
  56. @Override
  57. public T peek() {
  58. if(size==0)
  59. return null;
  60. else
  61. {
  62. return t[size-1];
  63. }
  64. }
  65. /*下表从1开始*/
  66. @Override
  67. public int search(T t) {
  68. for(int i= 0;i<size;i++)
  69. if(t.equals(this.t[i]))
  70. return i+1;
  71. return 0;
  72. }
  73. @Override
  74. public String toString() {
  75. StringBuilder sb = new StringBuilder();
  76. sb.append("ArrayStack:\n[\n");
  77. for (int i = size-1; i >=0; i--) {
  78. sb.append("   "+t[i].toString());
  79. if (i != size + 1) {
  80. sb.append("\n");
  81. }
  82. }
  83. sb.append("]");
  84. return sb.toString();
  85. }
  86. }

测试代码:

  1. public static void main(String[] args) {
  2. ArrayStack<String> arrayStack = new ArrayStack<>();
  3. arrayStack.push("C语言");
  4. arrayStack.push("C++");
  5. arrayStack.push("JAVA");
  6. arrayStack.push("数据结构");
  7. arrayStack.pop();
  8. arrayStack.peek();
  9. arrayStack.pop();
  10. System.out.println(arrayStack.toString());
  11. }

输出结果:

栈的链表实现

  1. package com.kiritor;
  2. /**
  3. * 栈的链表实现
  4. * @author Kiritor*/
  5. public class LinkStack<T> implements Stack<T>{
  6. /*将数据封装成结点*/
  7. class Node
  8. {
  9. private Node pre;
  10. private T data;
  11. }
  12. /*栈顶指针*/
  13. private Node top;
  14. private int size;//栈的大小
  15. public LinkStack() {
  16. this.top = null;
  17. this.size = 0;
  18. }
  19. @Override
  20. public boolean isEmpty() {
  21. return size==0;
  22. }
  23. @Override
  24. public void clear() {
  25. top = null;
  26. size = 0;
  27. }
  28. @Override
  29. public T pop() {
  30. if (top != null) {
  31. T t = top.data;
  32. // 改变栈顶指针
  33. top = top.pre;
  34. size--;
  35. return t;
  36. }
  37. return null;
  38. }
  39. @Override
  40. public boolean push(T data) {
  41. Node node = new Node();
  42. node.data = data;
  43. node.pre = top;
  44. // 改变栈顶指针
  45. top = node;
  46. size++;
  47. return true;
  48. }
  49. @Override
  50. public int length() {
  51. return size;
  52. }
  53. @Override
  54. public T peek() {
  55. return top.data;
  56. }
  57. /*下表从1开始*/
  58. @Override
  59. public int search(T t) {
  60. int count=0;
  61. for(Node node= top;node.pre!=null;node = node.pre)
  62. {
  63. count++;
  64. if(t.equals(node.data))
  65. return size - count;
  66. }
  67. return 0;
  68. }
  69. @Override
  70. public String toString() {
  71. StringBuilder sb = new StringBuilder();
  72. sb.append("LinkStack:"+length()+"\n[\n");
  73. int count=0;
  74. for (Node node = top;node!=null;node=node.pre) {
  75. count++;
  76. sb.append("   "+node.data.toString());
  77. if (count != size + 1) {
  78. sb.append("\n");
  79. }
  80. }
  81. sb.append("]");
  82. System.out.println(count);
  83. return sb.toString();
  84. }
  85. }

测试代码:

  1. public static void main(String[] args) {
  2. LinkStack<String> arrayStack = new LinkStack<>();
  3. arrayStack.push("C语言");
  4. arrayStack.push("C++");
  5. arrayStack.push("JAVA");
  6. arrayStack.push("数据结构");
  7. System.out.println(arrayStack.toString());
  8. }

结果就不贴出了
                       因为栈操作的特殊性,一般来说以数组方式实现的栈的效率是要高于链表实现的,

原因在于:其一数组的访问更快。其二由于只在栈顶进行操作并未涉及太大的元素移动

但是使用链式实现将数据包装成Node,在从其中取数据,还的维护栈顶指针和前驱指针。

栈的实现(JAVA)的更多相关文章

  1. Java 堆内存与栈内存异同(Java Heap Memory vs Stack Memory Difference)

    --reference Java Heap Memory vs Stack Memory Difference 在数据结构中,堆和栈可以说是两种最基础的数据结构,而Java中的栈内存空间和堆内存空间有 ...

  2. 栈的实现Java

    package practice; import java.util.Iterator; //栈 public class MyStack<T> implements Iterable&l ...

  3. 剑指offer【05】- 用两个栈实现队列(java)

    题目:用两个栈实现队列 考点:栈和队列 题目描述:用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 解题思路:每次psuh是时先将stack2清空放入stck1(保 ...

  4. 栈的实现——java

    和C++一样,JDK包中也提供了"栈"的实现,它就是集合框架中的Stack类.关于Stack类的原理,在"Java 集合系列07之 Stack详细介绍(源码解析)和使用示 ...

  5. 数组、栈、堆(java基础知识五)

    1.数组概述.定义格式 * A:数组概念 数组是存储同一种数据类型多个元素的集合.也可以看成是一个容器. 数组既可以存储基本数据类型,也可以存储引用数据类型. * B:数组定义格式 格式1:数据类型[ ...

  6. java虚拟机栈(关于java虚拟机内存的那些事)

    <深入理解 java 虚拟机> 读书扩展 作者:淮左白衣 写于 2018年4月13日16:26:51 目录 文章目录 java虚拟机栈是什么 特点 栈帧 局部变量表 什么时候抛出 `Sta ...

  7. 05.用两个栈实现队列 Java

    题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 思路 进栈: 直接进stack1 出栈: 若stack2不为空,则出栈. 否则,当stack1不为空时, ...

  8. (超详细)动手编写 — 栈、队列 ( Java实现 )

    目录 前言 栈 概念 栈的设计 编码实现 小结 队列 概念 队列的设计 编码实现 双端队列 概念 设计 编码 循环队列 循环队列 循环双端队列 声明 前言 栈 概念 什么是栈? **栈 **:是一种特 ...

  9. 数据结构之链表、栈和队列 java代码实现

    定义抽象节点类Node: package cn.wzbrilliant.datastructure; /** * 节点 * @author ice * */ public abstract class ...

随机推荐

  1. Hazelcast

    Hazelcast是一个高度可扩展的数据分发和集群平台.特性包括: 提供java.util.{Queue, Set, List, Map}分布式实现. 提供java.util.concurrency. ...

  2. C#微信公众号开发 -- (三)用户关注之后自动回复

    通过了上一篇文章之后的微信开发者验证之后,我们就可以做微信公众号的代码开发了. 当我们点击关注某个公众号的时候,有时候会发现他会自动给我们回复一条消息,比如欢迎关注XXX公众号.这个功能其实是在点击关 ...

  3. WordLight: highlights all occurrences of a selected text for VS2008

    https://visualstudiogallery.msdn.microsoft.com/ad686131-47d4-4c13-ada2-5b1a9019fb6f About This is a ...

  4. ImageIcon图像处理相关测试【一些特殊的处理方式】

    /*************以下源码通过测试******************************/ package cn.jason.ios.images; import java.awt.F ...

  5. v4l2简介

    V4L是linux内核中关于视频设备的子系统,为linux下的视频驱动提供了统一的接口,使应用程序可以使用统一的API操作不同的视频设备,简化视频系统的开发与维护 V4L2相比与V4L有更好的扩展性和 ...

  6. ajax的访问 WebService 的方法

    如果想用ajax进行访问 首先在web.config里进行设置 添加在 <webServices> <protocols> <add name= "HttpPo ...

  7. notepad++使用技巧

    1.将tab设置为插入4个空格而不是tab字符 1)点击设置-->首选项 2)选中转换为空格.点击蓝色数字,可以设置制表符宽度 2.对已有文档,进行tab和空格的相互转换 选中编辑-->空 ...

  8. JQ封装切换滚动功能

    /*---------控制滚动图片v1(作者:SFLYQ)-----------Options 配置对象,(用来配置控制元素的dom位置,初始化一些必要的对象或者方法)DoIni 初始化操作(初始化元 ...

  9. IDEA插件开发基础

    由于简易ORM的需要,想要做一些代码自动生成功能(通过右键菜单辅助) 半自动编写代码,故考虑需要开发IDE插件(我司现使用IDEA) 1.例子代码http://confluence.jetbrains ...

  10. 使用dynamic来简化反射实现

    dynamic是Framework4.0的新特性,dynamic的出现让C#具有了弱语言类型的特性,编译器在编译的时候,不再对类型进行检查,不会报错,但是运行时如果执行的是不存在的属性或者方法,运行程 ...