java-栈的实现
来源:互联网 发布:云豹直播源码破解版 编辑:程序博客网 时间:2024/05/21 17:23
栈作为常用的数据存储结构之一,存储的特点是“先进后出”,通常都是直接拿Java提供的Stack使用,那我们也可以自己动手去实现下栈,栈的存储结构分为顺序存储和链式存储,本篇先实现顺序存储。
一、基本实现
栈的顺序存储主要靠数组来存储数据,栈中还有一个比较重要的就是“栈顶指针”,不管入栈、出栈还是查看栈顶元素都要用到“栈顶指针”,所以这里可以把“栈顶指针”定义成一个int变量,等于数组最后一个元素的下标。
下面是具体的代码:
public class OrderStack { // 保存数据的数组 private Object[] data; // 栈顶指针 private int top = -1; // 栈中元素个数 private int size; /** * 无参构造,默认创建大小为10的数组 */ public OrderStack() { this(10); } /** * 带参构造,指定创建数组的大小 * * @param initialSize 数组的大小 * */ public OrderStack(int initialSize) { data = new Object[initialSize]; } /** * 入栈 * @param obj 入栈的数据 * */ public void push(Object obj) { if (top >= data.length - 1) { // 元素个数超出数组大小 System.out.println("栈满"); } else { data[++top] = obj; size++; } } /** * 出栈 * @return 返回栈顶的元素栈顶元素 */ public Object pop() { if (isEmpty()) { // 栈为空时抛出异常 throw new RuntimeException("栈为空"); } else { Object obj = data[top--]; size--; data[size] = null; // help GC return obj; } } /** * 查看栈顶元素,但并不出栈 * @return 返回栈顶的元素 */ public Object peek() { if (isEmpty()) { // 栈为空时抛出异常 throw new RuntimeException("栈为空"); } else { return data[top]; } } /** * 判断栈是否为空 * @return 为空返回true,否则false */ public boolean isEmpty() { return top == -1 ? true : false; } /** * 返回栈中元素的个数 * @return 栈中元素的个数 */ public int size() { return this.size; }}
测试如下:
public class Test { public static void main(String[] args) { // TODO Auto-generated method stub OrderStack orderStack = new OrderStack(); orderStack.push(10); orderStack.push(20); orderStack.push(30); orderStack.push(40); orderStack.push(50); orderStack.push(60); orderStack.push(70); orderStack.push(80); orderStack.push(90); orderStack.push(100); System.out.println("栈中元素个数:" + orderStack.size()); System.out.println("栈顶元素:" +orderStack.peek()); System.out.println("=============楚河汉界============="); System.out.println("出栈:" +orderStack.pop()); System.out.println("栈中元素个数:" + orderStack.size()); System.out.println("=============楚河汉界============="); }}
运行结果如下,出栈、查看栈顶元素、入栈都可以实现了:
二、push()方法的改进
但是如果我紧接着在入栈5个数据就会报“栈满”的提示,因为正在入栈方法中做了相应的处理,避免入栈的数据超出数组的大小。
public static void main(String[] args) { // ...上面代码省略... System.out.println("出栈:" +orderStack.pop()); System.out.println("栈中元素个数:" + orderStack.size()); System.out.println("=============楚河汉界============="); // 再入栈5个 orderStack.push(200); orderStack.push(210); orderStack.push(220); orderStack.push(230); orderStack.push(240); }
这个问题需要解决掉,毕竟这样的栈限制太大,可以在push方法中利用Arrays类中的copyOf()方法在数组满时动态的创建长度更长的数组,并将原数组的数据拷贝进去。
新的push()方法:
/** * 入栈 * @param obj 入栈的数据 */ public void push(Object obj) { if (top >= data.length - 1) { // 当数组满了,就创建一个新数组,长度为当前数组的2倍,并将当前数组的数据拷贝进去 data = Arrays.copyOf(data, data.length * 2); } data[++top] = obj; size++; }
这样不管插入多少个数据都没有问题了:
public class Test { public static void main(String[] args) { // TODO Auto-generated method stub OrderStack orderStack = new OrderStack(); orderStack.push(10); orderStack.push(20); orderStack.push(30); orderStack.push(40); orderStack.push(50); orderStack.push(60); orderStack.push(70); orderStack.push(80); orderStack.push(90); orderStack.push(100); orderStack.push(200); orderStack.push(210); orderStack.push(220); orderStack.push(230); orderStack.push(240); System.out.println("栈中元素个数:" + orderStack.size()); System.out.println("=============楚河汉界============="); }}
三、进一步完善
上面在定义时数组类型为Object,在push方法中定义的参数也为Object,这样就带来一个问题,我入栈的时候不管是什么类型的数据都可入栈,这样我们的栈就变成了“杂货铺”不便于使用,现在就需要通过使用泛型来约束栈保存数据的类型。代码主体不需要更改,只需要做一些更改。
public class **OrderStack<T>** { // 保存数据的数组 private Object[] data; // 栈顶指针 private int top = -1; // 栈中元素个数 private int size; /** * 无参构造,默认创建大小为10的数组 */ public OrderStack() { this(10); } /** * 带参构造,指定创建数组的大小 * * @param initialSize * 数组的大小 * */ public OrderStack(int initialSize) { data = new Object[initialSize]; } /** * 入栈 * @param obj 入栈的数据 */ public void push(**T obj**) { if (top >= data.length - 1) { // 当数组满了,就创建一个新数组,长度为当前数组的2倍,并将当前数组的数据拷贝进去 data = Arrays.copyOf(data, data.length * 2); } data[++top] = obj; size++; } /** * 出栈 * * @return 返回栈顶的元素栈顶元素 */ **public T pop()** { if (isEmpty()) { // 栈为空时抛出异常 throw new RuntimeException("栈为空"); } else { Object obj = data[top--]; size--; data[size] = null; // help GC **return (T) obj;** } } /** * 查看栈顶元素,但并不出栈 * * @return 返回栈顶的元素 */ **public T peek()** { if (isEmpty()) { // 栈为空时抛出异常 throw new RuntimeException("栈为空"); } else { **return (T) data[top];** } } /** * 判断栈是否为空 * * @return 为空返回true,否则false */ public boolean isEmpty() { return top == -1 ? true : false; } /** * 返回栈中元素的个数 * * @return 栈中元素的个数 */ public int size() { return this.size; }}
测试如下:
public class Test { public static void main(String[] args) { // 指定栈只能存储int数据 OrderStack<Integer> orderStack = new OrderStack<Integer>(); orderStack.push(10); orderStack.push(20); orderStack.push("abc"); // 此行代码将会报错,数据类型不匹配 }}
好了,到此最基本顺序栈已经差不多完成了,有什么问题欢迎指正。
生活不只是敲代码,如果你或你身边的人喜欢摄影或者生活的点点滴滴,可以关注下我亲爱的公众号~
阅读全文
0 0
- 栈的实现(JAVA)
- 栈的实现-----java
- 【java】栈的实现
- 栈的java实现
- 栈的Java实现
- 栈的实现-java
- 栈 的java实现
- Java栈的实现
- java栈的实现
- 栈的实现java
- Java 栈的实现
- Java 栈的实现
- java栈的实现
- 栈的java实现
- java 栈的实现
- java栈的实现
- java栈的实现
- Java栈的实现
- 看我是怎么学SLAM(二)——3D自主探索建图源码解读
- Spring-AOP 通过配置文件实现 环绕增强
- css居中总结
- android总体流程
- 文本自动摘要—tensorflow_textsum
- java-栈的实现
- Softmax
- 自定义控件之绘图篇:canvas变换与操作
- 基于树莓派利用红外二极管遥控空调,并加入homeassistant
- Django连接mysql 出现No module named ‘MySQLdb’.问题
- Spring-AOP 通过配置文件实现 异常抛出增强
- 机器人局部避障的动态窗口法(dynamic window approach)
- clion开发调试php7扩展
- QT之OpenGL