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

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日

相关文章

  • C、C++线性表基本操作的详细介绍

    我来详细讲解“C、C++线性表基本操作的详细介绍”。 一、线性表的定义 线性表是一种数据结构,它是由n个数据元素组成的有限序列,记为(a1,a2,…,an),其中a1是线性表的第一个元素,an是线性表的最后一个元素。除第一个元素之外,每一个元素有且仅有一个直接前驱元素,除了最后一个元素之外,每一个元素有且仅有一个直接后继元素。 线性表可以理解为一个一维数…

    数据结构 2023年5月17日
    00
  • 带你了解Java数据结构和算法之递归

    带你了解Java数据结构和算法之递归 什么是递归? 递归是一种算法或计算机程序的设计方法,在程序执行过程中直接或间接的调用自身。 递归的实现方式 递归的实现通常使用函数进行的。在函数中,我们首先检查停止条件(递归基)是否满足,如果满足,我们停止递归;否则,我们调用自身递归进行下一步计算。 递归的应用场景 递归通常在解决问题中使用。对于像树、图等复杂结构的遍历…

    数据结构 2023年5月17日
    00
  • PHP 数据结构队列(SplQueue)和优先队列(SplPriorityQueue)简单使用实例

    下面我来为大家详细讲解一下“PHP 数据结构队列(SplQueue)和优先队列(SplPriorityQueue)简单使用实例”的攻略。 一、SplQueue 首先,我们先来介绍一下SplQueue。SplQueue是一个双向队列,它基于一个双向链表实现,可以在队列的两端插入和删除元素,既可以按照先进先出的顺序来操作队列,也可以反过来按照先进后出的顺序来操作…

    数据结构 2023年5月17日
    00
  • Go 语言数据结构之双链表学习教程

    Go 语言数据结构之双链表学习教程 一、前言 双链表是常见的数据结构,Go语言作为一种静态类型的语言,自带指针类型支持,因此在实现双链表时相对比较容易。本文中,我们将介绍双链表的基础理论和实践应用,并结合代码实现来详细讲解。 二、实现双链表的基本操作 1. 创建双链表 创建双链表需要定义链表中存储的元素类型,以及定义一个结构体来表示双链表中的一个节点。 ty…

    数据结构 2023年5月17日
    00
  • 自制PHP框架之模型与数据库

    很好,下面我将为您详细讲解如何自制PHP框架中的模型与数据库部分。 什么是模型和数据库? 在讲解自制PHP框架的模型和数据库前,我们需要先了解什么是模型和数据库。在PHP框架架构中,模型是用来操作数据库的一种机制,用来处理对数据表的增删改查等操作,并且与数据库的连接是一定的。而数据库是一种数据存储工具,用于存储数据并提供数据操作的方法,例如数据的增删改查等。…

    数据结构 2023年5月17日
    00
  • mysql的Buffer Pool存储及原理解析

    下面我就来详细讲解一下“mysql的Buffer Pool存储及原理解析”的攻略。 Buffer Pool简介 在MySQL中,Buffer Pool是一个重要的概念,也可以说是MySQL最重要的性能优化建议之一。Buffer Pool是MySQL内存中缓存数据页的数据结构,用于加速数据的读写。 数据页 在MySQL中,数据是以数据页(page)为单位进行读…

    数据结构 2023年5月17日
    00
  • Java数据结构之优先级队列(堆)图文详解

    Java数据结构之优先级队列(堆)图文详解 什么是优先级队列(堆) 优先级队列(堆)是一种非常重要的数据结构,它能够更好地管理数据,分配任务等。优先级队列的本质就是一种特殊的队列,它是一种可以根据元素的优先级来出队的数据结构。 通常情况下,队列中存储了一系列具有优先级的数据。当我们从队列中取出元素时,优先级高的元素会先出队。因此,我们需要一种数据结构,来对这…

    数据结构 2023年5月17日
    00
  • [Week 18] 每日一题(C++,动态规划,线段树,数学)

    目录 [Daimayuan] T1 最长公共子序列(C++,DP,二分) 输入格式 输出格式 数据范围 输入样例 输出样例 解题思路 [Daimayuan] T2 喵喵序列(C++,序偶) 题目描述 输入格式 输出格式 样例输入 样例输出 样例说明 数据范围 双倍经验 解题思路: [Daimayuan] T3 漂亮数(C++,字符串) 输入描述 输出描述 输…

    算法与数据结构 2023年4月25日
    00
合作推广
合作推广
分享本页
返回顶部