栈是限制插入和删除仅仅能在一个位置上进行的表。该位置是表的末端,叫做栈的顶top。对栈的基本操作有进栈push和出栈pop,前者相当于插入。后者这是删除最后插入的元素。

栈有时又叫先进先出FIFO表。

因为栈操作是常数时间。因此除非在特殊情况下,栈不会产生明显改进。

栈的第一种实现方法是使用单链表。通过在表的顶端插入来实现push,通过删除表顶端元素实现pop。top操作仅仅是返回顶端元素的值。另外一种实现方法是使用数组,避免了链并且是更流行的解决方式。栈的栈顶用topOfStack来指向表示,对于空栈该值为-1。为将某个元素x推入栈中,我们使topOfStack加1然后置theItems[topOfStack]=x。

为了弹出栈顶元素,pop()返回theItems[topOfStack]然后topOfStack减1。

这些操作不仅以常数执行,并且是以非常快的常数时间执行。在某些机器上,若在带有自增和自减寻址功能的寄存器上操作,则整数的push和pop都能够写成一条机器指令。现代的计算机将栈操作作为指令系统的一部分,由此可见,栈非常可能是计算机在数组之后最主要的数据结构。

下面是一个用数组实现的栈,结构和数组非常像。但简化了操作,当中的main函数用作測试:

import java.util.Iterator;
import java.util.NoSuchElementException; public class MyStack<AnyType> implements Iterable<AnyType> {
private static final int DEFAULT_CAPACITY = 10; private int theSize;
private AnyType[] theItems;
private int topOfStack; public MyStack() {
clear();
} public void clear() {
theSize = 0;
topOfStack = -1;
ensureCapacity(DEFAULT_CAPACITY);
} public int size() {
return theSize;
} public boolean isEmpty() {
return size() == 0;
} public void trumToSize() {
ensureCapacity(size());
} @SuppressWarnings("unchecked")
public void ensureCapacity(int newCapacity) {
if (newCapacity < size()) {
return;
}
AnyType[] old = theItems;
theItems = (AnyType[]) new Object[newCapacity];
for (int i = 0; i <= topOfStack; i++) {
theItems[i] = old[i];
}
theSize = newCapacity;
} public AnyType top() {
if (size() == 0) {
throw new NullPointerException();
}
return theItems[topOfStack];
} public AnyType pop() {
if (size() == 0) {
throw new NullPointerException();
}
return theItems[topOfStack--];
} public void push(AnyType x) {
if (topOfStack + 1 == size()) {
ensureCapacity(size() * 2 + 1);
}
theItems[++topOfStack] = x;
} @Override
public Iterator<AnyType> iterator() {
return new StackIterator();
} private class StackIterator implements Iterator<AnyType> {
private int current = 0; public boolean hasNext() {
return current <= topOfStack;
} public AnyType next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return theItems[current++];
}
} public static void main(String[] args) {
MyStack<Integer> stack = new MyStack<Integer>();
stack.push(1);
stack.push(2);
stack.push(3);
stack.pop();
stack.push(4);
stack.push(5);
Iterator<Integer> iterator = stack.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
}
}

输出结果:

1 2 4 5

最新文章

  1. svn更新路径,解决办法详细步骤,eclipse里面的更新方法,svn废弃位置,Windows环境,svn服务器地址换了,如何更新本地工作目录
  2. UICollectionView移动
  3. MFC创建对话框组件对应变量并进行设置值(VS2010)
  4. go对json的解析处理
  5. Android 实现切换主题皮肤功能(类似于众多app中的 夜间模式,主题包等)
  6. WIFI环境下Android手机和电脑通信
  7. [洛谷1580]yyy loves Easter_Egg I
  8. Unityclient通信測试问题处理(二)
  9. Quartz1.8.5例子(七)
  10. iPhone开发:Objective C 代码规范-iOS总结版
  11. VC操作Image的三种方法(收集)
  12. 关于利用input的file属性在页面添加图片的问题
  13. springboot~openfeign从此和httpClient说再见
  14. javaweb中上传图片并显示图片,用我要上传课程信息(里面包括照片)这个例子说明
  15. bzoj 4571: [Scoi2016]美味 (主席树)
  16. 一张图解释IaaS,PaaS,SaaS
  17. Android 开发 音视频从入门到提高 任务列表 转载
  18. 洛谷P3980 志愿者招募
  19. react脚手架搭建及配置
  20. 利用include动作实现参数传递

热门文章

  1. 在npm当中发布自己的包的方法
  2. 【14】redux 之 redux-actions
  3. BZOJ 2813: 奇妙的Fibonacci
  4. dedeCMS php标签使用说明和数据库查询说明
  5. HTML 文档之 Head 最佳实践
  6. JSTL获取Session的ID与获取文件的真实路径与项目名称
  7. Http协议和Tomcat服务器安装与eclipse集成(重要)
  8. Linux下的软连接和硬链接
  9. usb 2.0 operation mode
  10. 学习总结——JMeter做http接口压力测试