深入学习数据结构之栈(二)
上一篇文章我们描述了什么是栈,以及Java中Stack的实现方式。
先前介绍了栈有两种实现方式,一种是通过数组实现(可以参考Java的Stack),另外一种就是链表,今天我们手写一个通过链表实现栈的功能。
public class LinkStack<E> { private Node node; private int elementCount; // 初始化 public LinkStack() { node = null; elementCount = 0; } // 添加元素到栈顶 public E push(E item) { // 创建元素 Node next = new Node(item); if (node == null) { node = next; } else { next.nextNode = node; node = next; } elementCount++; return item; } // 弹出栈顶元素 public synchronized E pop() { if (node == null) { return null; } Node top = node; node = top.nextNode; top.nextNode = null; elementCount--; return top.data; } // 读取栈顶元素 public synchronized E peek() { if (node == null) { return null; } Node top = node; return top.data; } // 判断栈是否为空 public boolean empty() { return size() == 0; } // 读取栈大小 public int size() { return elementCount; } // 清空栈数据 public void clear() { node = null; elementCount = 0; } class Node { private E data; private Node nextNode; public Node(E data) { this.data = data; } } }
实现逻辑:
(一)结构:LinkStack使用内部对象保存我们需要保存的数据,以及指向下一个节点的指针。
(二)添加:当栈为空时,创建节点,将栈顶指针指向新创建节点,更新计数器
当栈不为空时,创建节点,将新创建的节点指向当前栈顶节点,同时将栈顶节点指针指向新创建节点。更新计数器
(三)弹出:获取栈顶节点,同时将栈顶指针指向下一个节点,同时断开原栈顶节点和栈的关联关系。更新计数器
(四)清除:将栈顶指针置为null,更新计数器
对比:
数组实现:当数量超过数组大小时需要重新开辟新的数组,同时将原数组数据进行拷贝,一定程度上浪费了内存和性能,
Java中Stack 的 使用了synchronized 线程安全机制,降低了程序性能。
链表实现:通过指针实现,比较灵活。
注:上面案例中没有增加线程安全考虑,仅仅只是实现了基础功能。
总结:
Stack 继承了Vector ,实现方法上全部使用synchronized 关键字,而且使用数组实现,存在需要不断扩容问题。因此不推荐使用Stack,现在Java中可以使用Deque进行代替。

浙公网安备 33010602011771号