📜  使用链表的 java 堆栈 - Java (1)

📅  最后修改于: 2023-12-03 14:49:58.317000             🧑  作者: Mango

使用链表的 Java 堆栈

在 Java 中,堆栈(Stack)是一种常见的数据结构,它常常用于实现方法调用、表达式求值、括号匹配等功能。在本文中,我们将介绍如何使用链表实现 Java 堆栈,并提供相应的代码示例。

链表介绍

链表(Linked List)是一种线性数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向后继节点的指针。相对于数组,链表具有以下优势:

  • 链表的节点可以动态的添加或删除,不需要预先分配内存空间,因此更加灵活。
  • 链表的节点在内存中可以分散存储,因此不需要连续的内存空间,相对于数组更加节约空间。

但是,链表的缺点也很明显:由于每个节点需要存储指向后继节点的指针,因此空间开销更大;同时,访问链表的任意一个节点的时间复杂度是 O(n),相对于数组的 O(1) 更加高。

链表实现堆栈

在使用链表实现堆栈时,我们可以将链表的头结点作为堆栈的栈顶,使用一个指针不断指向当前的栈顶节点。每次入栈操作就在链表的头部插入一个新的节点,每次出栈操作就删除链表头部的节点。

下面是使用链表实现堆栈的 Java 代码示例:

public class LinkedListStack<E> {
    
    private Node<E> top;
    private int size;
    
    private class Node<E> {
        private E item;
        private Node<E> next;
    }
    
    public LinkedListStack() {
        top = null;
        size = 0;
    }
    
    public void push(E item) {
        Node<E> newNode = new Node<>();
        newNode.item = item;
        newNode.next = top;
        top = newNode;
        size++;
    }
    
    public E pop() {
        if (top == null) {
            throw new NoSuchElementException();
        }
        E item = top.item;
        top = top.next;
        size--;
        return item;
    }
    
    public boolean isEmpty() {
        return top == null;
    }
    
    public int size() {
        return size;
    }
}

在上面的代码中,我们定义了一个泛型类 LinkedListStack,其中:

  • Node 是链表的节点类,包含一个数据元素和一个指向后继节点的指针。
  • push(E item) 方法将一个元素入栈,即在链表头部插入一个新的节点。
  • pop() 方法将一个元素出栈,即从链表头部删除一个节点并返回它的数据元素。
  • isEmpty() 方法用于判断堆栈是否为空。
  • size() 方法用于返回当前堆栈的大小。
使用示例

下面是如何使用上述代码使用链表实现堆栈的示例:

public static void main(String[] args) {
    LinkedListStack<Integer> stack = new LinkedListStack<>();
    
    stack.push(1);
    stack.push(2);
    stack.push(3);
    
    System.out.println(stack.pop()); // 3
    System.out.println(stack.pop()); // 2
    
    stack.push(4);
    
    System.out.println(stack.pop()); // 4
    System.out.println(stack.pop()); // 1
    
    System.out.println(stack.isEmpty()); // true
    System.out.println(stack.size()); // 0
}

在上面的示例中,我们依次将 1、2、3 三个元素入栈,然后依次出栈前两个元素,并将 4 入栈,最后依次出栈前一个元素,最终得到栈为空的结果。

总结

使用链表实现堆栈是一种常见的做法,它可以避免固定长度的数组带来的空间浪费问题。在实现时,我们使用链表的头部作为栈顶,然后使用一个指针指向当前的栈顶节点。每次入栈操作就在链表的头部插入一个新的节点,每次出栈操作就删除链表头部的节点即可。