看动画学算法之:栈stack

简介: 看动画学算法之:栈stack

目录



简介


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


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


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


栈的构成


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


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


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


先看下入栈的动画:



再看下出栈的动画:


20200712230940583.gif


栈的实现


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


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


使用数组来实现栈


如果使用数组来实现栈的话,我们可以使用数组的最后一个节点作为栈的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;
    }
}
相关文章
|
1月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
62 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
1月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
30 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
17天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
算法
数据结构与算法二:栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式
这篇文章讲解了栈的基本概念及其应用,并详细介绍了中缀表达式转换为后缀表达式的算法和实现步骤。
44 3
|
1月前
|
算法 C++
【算法单调栈】 矩形牛棚(C/C++)
【算法单调栈】 矩形牛棚(C/C++)
|
3月前
|
算法
【算法】栈算法——逆波兰表达式求值
【算法】栈算法——逆波兰表达式求值
|
3月前
|
存储 算法
【算法】栈算法——最小栈
【算法】栈算法——最小栈
|
3月前
|
算法
【算法】栈算法——栈的压入、弹出序列
【算法】栈算法——栈的压入、弹出序列
|
4月前
|
算法 Java 开发者
Java面试题:Java内存探秘与多线程并发实战,Java内存模型及分区:理解Java堆、栈、方法区等内存区域的作用,垃圾收集机制:掌握常见的垃圾收集算法及其优缺点
Java面试题:Java内存探秘与多线程并发实战,Java内存模型及分区:理解Java堆、栈、方法区等内存区域的作用,垃圾收集机制:掌握常见的垃圾收集算法及其优缺点
39 0
|
4月前
|
存储 算法 Java
Java面试题:解释JVM的内存结构,并描述堆、栈、方法区在内存结构中的角色和作用,Java中的多线程是如何实现的,Java垃圾回收机制的基本原理,并讨论常见的垃圾回收算法
Java面试题:解释JVM的内存结构,并描述堆、栈、方法区在内存结构中的角色和作用,Java中的多线程是如何实现的,Java垃圾回收机制的基本原理,并讨论常见的垃圾回收算法
63 0