数据结构 - 链栈

217 阅读3分钟

前言

前文我们说了顺序栈的介绍与使用,这次来说说 链栈,阅读时长约 7min

链栈

介绍:

栈的链式储存结构称为链栈。

规格:

链栈的节点类型与链式线性表的节点类型定义相同,不同的是它是仅在表头进行操作的单链表;链栈通常用不带头节点的单链表来实现,栈顶指针就是链表的头指针

特点:
  1. 空间是动态的,可以利用容量碎片进行动态分配,节省空间
  2. 链栈比起栈进行添加删除操作更快
复杂度分析

链栈属于常见的一种线性结构,对于进栈和退栈而言,时间复杂度都为 O(1)

前奏准备

本文章讲解所用的编程语言为 Java

基本方法

链栈与链表一致都是用结点来实现的;首先需要创建一个结点类 与 链栈方法类

Node.java

创建结点类

 public class Node {
     public Object data; //存储的实际数据
     public Node next;// 指向下一个节点的对象
 ​
     public Node(Object data) {
         this.data = data;
     }
 ​
     public Node(Object data, Node next) {
         this.data = data;
         this.next = next;
     }
 }
LinkStack.java

首先需要定义一个 top 用于指向栈顶元素的位置,默认数据域为null;

所需的方法不多,主要的为 入栈出栈;较为简单的清空与判空已经直接写好就不单独拿出来了,不过这个获取长度有点不一样,可以仔细看看;

 public class LinkStack {
     // 使 top 定义为一个链式结点
     private Node top;
 ​
     public LinkStack() {
         top = null; // 默认为空
     }
 ​
     // 清空栈
     public void clear() { top = null;}
     
     // 栈是否为空
     public boolean isEmpty() { return top == null; }
     
     // 添加入栈
     public void push(Object e) {}
 ​
     // 删除出栈
     public Object pop(Object e) {}
     
     // 取出栈顶元素
     public Object peek() {}
     
     // 栈中元素的个数
     public int length() {}
 ​
     // 输出从栈顶到栈顶的所有元素
     public void display() {}
 ​

前奏准备完毕后,我们就可以开始重写方法了 (●'◡'●)

push(入栈)

入栈操作是将指定结点元素插入到链栈的栈顶,使其成为新的栈顶元素,类型为 Object

入栈方法的思路:
  1. 创建新的结点
  2. 新结点的下一个指向栈顶
  3. 成为新的栈顶
代码示例
     // 添加入栈
     public void push(Object e) {
         Node node = new Node(e);
         node.next = top;
         top = node;
     }
图文解析

pop(出栈)

入栈操作是将栈顶结点从链栈中移去,并返回该结点数据域的值

出栈方法的思路:
  1. 判断链栈是否为空
  2. 确定要删除的栈顶结点
  3. 修改指向,将栈顶结点从链栈中移去,并返回被删除结点的数据域的值
代码示例
     // 删除出栈
     public Object pop(Object e) {
         if (isEmpty()) {
             return null;
         } else {
             Node node = top;
             top = top.next;
             return node.data;
         }
     }
图文解析

peek(取出)

peek 用于取出栈顶结点

取出方法的思路:
  1. 判断链栈是否为空
  2. 若不为空,返回当前栈顶结点的数据域的值
代码示例
     // 取出栈顶元素
     public Object peek() {
         if (isEmpty()) {
             return null;
         } else {
             return top.data;
         }
     }

length(长度)

length 用于计算出链表中所链表中所包含的数据元素的个数并返回其值

取出方法的思路:
  1. 创建 node 指向栈顶元素
  2. 定义length长度,用于记录长度
  3. 从栈顶元素开始向后查找,直到node指向为空
  4. 每成功循环一次,length长度加一;
  5. 返回长度
代码示例
     // 栈中元素的个数
     public int length() {
         Node node = top;
         int len = 0;
         while (node != null) {
             node = node.next;
             ++len;
         }
         return len;
     }

display(输出)

display 用于从栈顶开始循环向下,输出从栈顶到栈顶的所有元素

代码示例
     // 输出从栈顶到栈顶的所有元素
     public void display() {
         Node node = top;
         while (node != null) {
             System.out.println(node.data);
             node = node.next;
         }
     }

打印示例

最后我们将所有方法测试一下~

以上就是链栈的介绍与方法实现啦 ( •̀ ω •́ )✧