Java数据结构专题解析之栈和队列的实现

yizhihongxing

Java数据结构专题解析之栈和队列的实现

什么是栈和队列?

在计算机科学中,(Stack)和队列(Queue)都是常见的数据结构,用于解决许多问题。它们都是线性数据结构,但它们的元素访问顺序不同。

  • 栈是先进后出(Last In First Out,LIFO)的结构,即最后放入栈中的元素最先被访问。
  • 队列是先进先出(First In First Out,FIFO)的结构,即最早放入队列中的元素最先被访问。

举个例子,我们生活中很常见的一个栈就是桶,不断往桶里踩东西,但是只有当最上面的东西被取走之后,第二层才能被取走,以此类推;而队列则类似排队,先来的先被服务,后来的等待在队列中。

栈的实现

栈的常见实现方式是使用数组或链表,这里我们采用链表来实现。一个栈包含两个主要操作:压入(push)和弹出(pop)。在链表实现中,我们需要每次将新元素插入链表的头部,同时我们也需要记录当前栈顶元素的位置,以便在弹出元素时能够快速访问。

以下是一段Java实现的示例代码:

public class MyStack<T> {
    // 内部类,代表链表的节点
    private class Node {
        // 数据
        private T data;
        // 下一节点
        private Node next;
        // 构造函数
        public Node(T data, Node next) {
            this.data = data;
            this.next = next;
        }
    }
    // 栈顶节点
    private Node top = null;
    // 栈的大小
    private int size = 0;

    // 压入元素
    public void push(T data) {
        // 新建节点
        Node newNode = new Node(data, top);
        // 更新栈顶
        top = newNode;
        // 更新大小
        size++;
    }

    // 弹出栈顶元素
    public T pop() throws Exception {
        if (top == null) {
            throw new Exception("Stack is empty!");
        }
        // 取出栈顶元素
        T data = top.data;
        // 更新栈顶
        top = top.next;
        // 更新大小
        size--;
        return data;
    }

    // 获取栈顶元素
    public T peek() throws Exception {
        if (top == null) {
            throw new Exception("Stack is empty!");
        }
        return top.data;
    }

    // 判断栈是否为空
    public boolean isEmpty() {
        return top == null;
    }

    // 获取栈的大小
    public int getSize() {
        return size;
    }
}

队列的实现

队列也是可以使用数组或链表来实现,这里我们采用链表实现。一个队列包含两个主要操作:入队(enqueue)和出队(dequeue)。在链表实现中,我们需要每次将新元素插入链表的尾部,同时我们也需要记录队列的头部和尾部位置,以便在出队时能够快速访问。

以下是一段Java实现的示例代码:

public class MyQueue<T> {
    // 内部类,代表链表的节点
    private class Node {
        // 数据
        private T data;
        // 下一节点
        private Node next;
        // 构造函数
        public Node(T data, Node next) {
            this.data = data;
            this.next = next;
        }
    }
    // 队列头
    private Node head = null;
    // 队列尾
    private Node tail = null;
    // 队列大小
    private int size = 0;

    // 入队
    public void enqueue(T data) {
        // 新建节点
        Node newNode = new Node(data, null);
        if (tail == null) {
            // 如果队列为空,则头、尾节点都为新节点
            head = tail = newNode;
        } else {
            // 如果队列不为空,则将新节点插入到尾部
            tail.next = newNode;
            tail = newNode;
        }
        // 更新队列大小
        size++;
    }

    // 出队
    public T dequeue() throws Exception {
        if (head == null) {
            throw new Exception("Queue is empty!");
        }
        // 取出队列头元素
        T data = head.data;
        head = head.next;
        if (head == null) {
            // 如果出队后队列为空,则尾节点设为null
            tail = null;
        }
        // 更新队列大小
        size--;
        return data;
    }

    // 获取队列头元素
    public T getHead() throws Exception {
        if (head == null) {
            throw new Exception("Queue is empty!");
        }
        return head.data;
    }

    // 判断队列是否为空
    public boolean isEmpty() {
        return head == null;
    }

    // 获取队列大小
    public int getSize() {
        return size;
    }
}

示例说明

示例一

假设我们需要对一个字符串进行逆序输出,可以使用栈来实现。将字符串逐个字符压入栈中,然后依次弹出栈顶元素并输出即可。

以下是Java实现的示例代码:

public static void reverseString(String str) throws Exception {
    MyStack<Character> stack = new MyStack<>();
    // 将字符串逐个字符压入栈中
    for (int i = 0; i < str.length(); i++) {
        stack.push(str.charAt(i));
    }
    // 依次弹出栈顶元素并输出
    while (!stack.isEmpty()) {
        System.out.print(stack.pop());
    }
}

示例二

假设我们需要对一组数进行先进先出的排序,可以使用队列来实现。将数列中的数依次入队,然后依次将队列中的元素出队并输出即可。

以下是Java实现的示例代码:

public static void sortNumberList(int[] nums) throws Exception {
    MyQueue<Integer> queue = new MyQueue<>();
    // 将数列中的数依次入队
    for (int i = 0; i < nums.length; i++) {
        queue.enqueue(nums[i]);
    }
    // 依次出队并输出队列中的元素
    while (!queue.isEmpty()) {
        System.out.print(queue.dequeue() + " ");
    }
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java数据结构专题解析之栈和队列的实现 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • 比特币区块链的数据结构

    让我来为你详细讲解比特币区块链的数据结构。 1. 区块链的定义 比特币区块链是一个去中心化的、可追溯的、公共的、可验证的交易数据库。每一笔交易都通过哈希算法,与之前的交易连接成一个区块,形成了一个数据结构链,也就是“区块链”。 2. 区块链的数据结构 区块链的数据结构由区块、交易和哈希三部分组成: 区块 区块是区块链数据结构的基本单位,每一个区块代表着一段时…

    数据结构 2023年5月17日
    00
  • 「分治」黑白棋子的移动

    本题为3月23日23上半学期集训每日一题中A题的题解 题面 题目描述 有2n个棋子(n≥4)排成一行,开始位置为白子全部在左边,黑子全部在右边,如下图为n=5的情形: ○○○○○●●●●● 移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能…

    算法与数据结构 2023年4月18日
    00
  • C++ 超详细分析数据结构中的时间复杂度

    C++ 超详细分析数据结构中的时间复杂度攻略 什么是时间复杂度? 时间复杂度是用来衡量算法效率的指标,它表示的是算法的执行时间与问题规模之间的关系,通常用大O记法来表示。 如何分析时间复杂度? 1. 常见时间复杂度 以下是常见的时间复杂度及其对应的执行次数: 时间复杂度 对应执行次数 O(1) 常数级别 O(log n) 对数级别 O(n) 线性级别 O(n…

    数据结构 2023年5月17日
    00
  • C语言数据结构之迷宫问题

    C语言数据结构之迷宫问题 迷宫问题是一种基本的搜索问题,其中需要在一个矩阵中寻找从起点到终点的路径。在本篇文章中,我们将以C语言为例,介绍迷宫问题的完整攻略。 准备工作 在开始之前,我们先要准备好数据结构。为了表示迷宫,我们使用一个二维数组。其中,0表示可以通过的路,1表示障碍物不可通过。为了记录路径,我们还需要使用一个二维数组来表示每个格子是否已经被访问过…

    数据结构 2023年5月17日
    00
  • 使用C语言详解霍夫曼树数据结构

    使用C语言详解霍夫曼树数据结构 什么是霍夫曼树 霍夫曼树是一种带权路径长度最短的树,也称为最优二叉树,它是优化编码的核心算法。 在霍夫曼树中,每个叶子节点对应一个字符,该节点的权值为该字符出现的次数。当然,字符可以是任何数据类型。生成霍夫曼树后,在对每个字符进行编码时,字符在霍夫曼树中的路径即为其编码。(一般规定,一条从根到叶子的路径上只出现0或1,从根到某…

    数据结构 2023年5月17日
    00
  • C语言数据结构之算法的时间复杂度

    关于C语言数据结构之算法的时间复杂度,需要先了解一些基本概念。 什么是时间复杂度 时间复杂度是算法的一种衡量标准,用于评估算法的执行效率。表示代码执行的时间和数据量之间的关系,通常用大O符号来表示,称为“大O记法”。 时间复杂度的分类 时间复杂度可分为以下几类: 常数阶:O(1) 对数阶:O(log n) 线性阶:O(n) 线性对数阶:O(n log n) …

    数据结构 2023年5月17日
    00
  • Codeforces Round 868 Div 2

    A. A-characteristic (CF 1823 A) 题目大意 要求构造一个仅包含\(1\)和 \(-1\)的长度为 \(n\)的数组 \(a\),使得存在 \(k\)个下标对 \((i, j), i < j\)满足 \(a_i \times a_j = 1\)。 解题思路 当有\(x\)个 \(1\), \(y\)个 \(-1\)时,其满足…

    算法与数据结构 2023年4月30日
    00
  • C语言 超详细总结讲解二叉树的概念与使用

    C语言 超详细总结讲解二叉树的概念与使用 1. 什么是二叉树? 二叉树是一种树状数据结构,其中每个节点最多有两个子节点,被称为左子节点和右子节点。具有以下几个特点: 每个节点最多有两个子节点; 左子节点可以为空,右子节点也可以为空; 二叉树的每个节点最多有一个父节点; 二叉树通常定义为递归模式定义,即每个节点都可以看做一棵新的二叉树。 2. 二叉树的遍历方式…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部