简介

栈应该是一种非常简单并且非常有用的数据结构了。栈的特点就是先进后出FILO或者后进先出LIFO。

实际上很多虚拟机的结构都是栈。因为栈在实现函数调用中非常的有效。

今天我们一起来看学习一下栈的结构和用法。

栈的构成

栈一种有序的线性表,只能在一端进行插入或者删除操作。这一端就叫做top端。

定义一个栈,我们需要实现两种功能,一种是push也就是入栈,一种是pop也就是出栈。

当然我们也可以定义一些其他的辅助功能,比如top:获取栈上最顶层的节点。isEmpty:判断栈是否为空。isFull:判断栈是否满了之类。

先看下入栈的动画:

再看下出栈的动画:

栈的实现

具有这样功能的栈是怎么实现呢?

一般来说栈可以用数组实现,也可以用链表来实现。

使用数组来实现栈

如果使用数组来实现栈的话,我们可以使用数组的最后一个节点作为栈的head。这样在push和pop栈的操作的时候,只需要修改数组中的最后一个节点即可。

我们还需要一个topIndex来保存最后一个节点的位置。

实现代码如下:

public class ArrayStack {

    //实际存储数据的数组
private int[] array;
//stack的容量
private int capacity;
//stack头部指针的位置
private int topIndex; public ArrayStack(int capacity){
this.capacity= capacity;
array = new int[capacity];
//默认情况下topIndex是-1,表示stack是空
topIndex=-1;
} /**
* stack 是否为空
* @return
*/
public boolean isEmpty(){
return topIndex == -1;
} /**
* stack 是否满了
* @return
*/
public boolean isFull(){
return topIndex == array.length -1 ;
} public void push(int data){
if(isFull()){
System.out.println("Stack已经满了,禁止插入");
}else{
array[++topIndex]=data;
}
} public int pop(){
if(isEmpty()){
System.out.println("Stack是空的");
return -1;
}else{
return array[topIndex--];
}
}
}

使用动态数组来实现栈

上面的例子中,我们的数组大小是固定的。也就是说stack是有容量限制的。

如果我们想构建一个无限容量的栈应该怎么做呢?

很简单,在push的时候,如果栈满了,我们将底层的数组进行扩容就可以了。

实现代码如下:

public void push(int data){
if(isFull()){
System.out.println("Stack已经满了,stack扩容");
expandStack();
}
array[++topIndex]=data;
} //扩容stack,这里我们简单的使用倍增方式
private void expandStack(){
int[] expandedArray = new int[capacity* 2];
System.arraycopy(array,0, expandedArray,0, capacity);
capacity= capacity*2;
array= expandedArray;
}

当然,扩容数组有很多种方式,这里我们选择的是倍增方式。

使用链表来实现

除了使用数组,我们还可以使用链表来创建栈。

使用链表的时候,我们只需要对链表的head节点进行操作即可。插入和删除都是处理的head节点。

public class LinkedListStack {

    private Node headNode;

    class Node {
int data;
Node next;
//Node的构造函数
Node(int d) {
data = d;
}
} public void push(int data){
if(headNode == null){
headNode= new Node(data);
}else{
Node newNode= new Node(data);
newNode.next= headNode;
headNode= newNode;
}
} public int top(){
if(headNode ==null){
return -1;
}else{
return headNode.data;
}
} public int pop(){
if(headNode ==null){
System.out.println("Stack是空的");
return -1;
}else{
int data= headNode.data;
headNode= headNode.next;
return data;
}
} public boolean isEmpty(){
return headNode==null;
}
}

本文的代码地址:

learn-algorithm

本文已收录于 http://www.flydean.com/10-algorithm-stack/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

最新文章

  1. SurfaceView 绘制分形图
  2. 【前端】从输入URL到页面加载完成的过程中都发生了什么事情
  3. Stanford NLP 学习笔记2:文本处理基础(text processing)
  4. 消息中间件与JMS标准
  5. Codeforces 549B. Looksery Party[构造]
  6. XSHELL下直接下载文件到本地(Windows)
  7. [转载] nosql 数据库的分布式算法
  8. js继承实例
  9. 自定义控件winfrom
  10. JQuery验证工具
  11. php练习6——面向对象编程(打印乘法表)
  12. Oracle translate 函数
  13. 物理机与虚拟机IP互ping通,而互ping主机名不通
  14. Arduino 入门程序示例之一排 LED(2015-06-11)
  15. Jedis Client的使用以及序列化
  16. CAReplicatorLayer复制Layer和动画, 实现神奇的效果
  17. 我必须得告诉大家的MySQL优化原理
  18. BZOJ1515 : [POI2006]Lis-The Postman
  19. 28.Mysql权限与安全
  20. 20172302《程序设计与数据结构》实验三 敏捷开发与XP实践报告

热门文章

  1. Linux 网络和端口命令
  2. 解决servlet中get方式中中文乱码问题前驱(一):装饰者模式再理解
  3. canvas——离屏
  4. php检测数组长度的函数sizeof count
  5. centos7 误用 cat 打开了一个很大的文件
  6. C++之常指针,指针常量,函数指针,const用法总结
  7. C#使用异步需要注意的几个问题
  8. 哦?原来这就是 JVM 垃圾!
  9. adb 常用命令大全(1)- 汇总
  10. Spring MVC拦截器浅析