Java数据结构与算法之栈(Stack)实现详解

yizhihongxing

Java数据结构与算法之栈(Stack)实现详解

1. 栈的概念及用途

栈(Stack)是一种线性数据结构,它具有“后进先出(Last In First Out, LIFO)”的特点。栈可以看成是一种特殊的列表,列表中的元素只能通过栈顶加入或删除,称为入栈和出栈。

栈的应用非常广泛,例如在函数调用时,系统会自动为每个函数创建一个栈,用于存储函数调用过程中产生的临时数据,当函数返回时,系统会自动弹出栈顶元素,恢复上一层的函数调用。此外,栈还可以用于解决很多算法问题,例如表达式求值、括号匹配、图搜索等等。

2. 栈的实现

栈的实现方式有多种,例如使用数组和使用链表等。在本文中,我们将主要介绍使用数组实现栈的方法。

2.1 栈的定义

首先,我们需要定义一个栈类,表示一个栈对象。一个简单的栈类定义如下:

public class MyStack {
    private int[] stackArray; // 存储栈元素的数组
    private int top; // 栈顶指针

    // 构造方法,创建指定大小的栈
    public MyStack(int size) {
        stackArray = new int[size];
        top = -1;
    }

    // 将元素压入栈顶
    public void push(int element) {
        stackArray[++top] = element;
    }

    // 弹出栈顶元素
    public int pop() {
        return stackArray[top--];
    }

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

    // 获取栈大小
    public int size() {
        return top + 1;
    }

    // 获取栈顶元素
    public int peek() {
        return stackArray[top];
    }
}

以上代码定义了一个名为MyStack的栈类,包含了栈的主要操作,例如pushpopisEmptysizepeek等。在这个类中,我们使用一个整型数组stackArray来存储栈中的元素,使用一个整数top来表示栈顶的指针,初始值为-1。

2.2 栈的使用

接下来,我们来演示一下如何使用MyStack类。假设我们需要将一个整数数组中的元素反转,即将数组中的最后一个元素放到最前面,倒数第二个元素放到第二个位置,以此类推。我们可以使用栈来实现这个功能,代码如下:

public static void reverseArray(int[] array) {
    MyStack stack = new MyStack(array.length);
    // 将元素压入栈中
    for (int i = 0; i < array.length; i++) {
        stack.push(array[i]);
    }
    // 将栈中元素依次弹出,赋给原数组
    for (int i = 0; i < array.length; i++) {
        array[i] = stack.pop();
    }
}

以上代码定义了一个名为reverseArray的方法,该方法接受一个整数数组作为参数,然后使用MyStack类将数组中的元素倒序排列。在这个方法中,我们首先创建了一个MyStack对象,并将原数组的元素依次压入栈中。然后,我们再依次弹出栈中的元素,赋给原数组即可。

下面,我们再演示一个栈的应用,检查字符串中的括号是否匹配。如果匹配,返回true,否则返回false。

public static boolean checkBrackets(String str) {
    MyStack stack = new MyStack(str.length());
    // 遍历字符串中的字符
    for (int i = 0; i < str.length(); i++) {
        char c = str.charAt(i);
        switch (c) {
            case '(':
            case '[':
            case '{':
                // 将左括号压入栈中
                stack.push(c);
                break;
            case ')':
                // 如果栈顶元素是左圆括号,则弹出栈顶元素
                if (stack.peek() == '(') {
                    stack.pop();
                } else {
                    return false; // 括号不匹配
                }
                break;
            case ']':
                // 如果栈顶元素是左方括号,则弹出栈顶元素
                if (stack.peek() == '[') {
                    stack.pop();
                } else {
                    return false; // 括号不匹配
                }
                break;
            case '}':
                // 如果栈顶元素是左花括号,则弹出栈顶元素
                if (stack.peek() == '{') {
                    stack.pop();
                } else {
                    return false; // 括号不匹配
                }
                break;
        }
    }
    // 如果栈为空,则括号匹配
    return stack.isEmpty();
}

以上代码定义了一个名为checkBrackets的方法,该方法接受一个字符串作为参数,然后检查字符串中的括号是否匹配。在这个方法中,我们首先创建了一个MyStack对象,然后遍历字符串中的每个字符。如果当前字符是左括号,就将其压入栈中。如果当前字符是右括号,则与栈顶元素进行匹配,如果可以匹配就弹出栈顶元素,否则就返回false。如果遍历完整个字符串之后,栈为空,则说明括号匹配,返回true,否则返回false。

3. 总结

本文介绍了栈的基本概念和使用方法,实现了一个简单的栈类,并演示了栈的两个常见应用——数组反转和括号匹配。栈是一种简单而有用的数据结构,熟练掌握栈的使用方法对程序员来说非常重要。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java数据结构与算法之栈(Stack)实现详解 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 浅谈JVM内存溢出原因和解决思路

    浅谈JVM内存溢出原因和解决思路 1. JVM内存溢出原因 JVM内存溢出是指在Java虚拟机运行过程中,无法分配到足够的内存空间,导致程序抛出OutOfMemoryError异常。以下是一些常见的导致JVM内存溢出的原因: 1.1 内存泄漏 内存泄漏是指程序中已经不再使用的对象仍然被引用,导致垃圾回收器无法回收这些对象所占用的内存。常见的内存泄漏情况包括:…

    other 2023年8月2日
    00
  • Linux之进程的虚拟地址空间,逻辑地址和物理地址,进程管理命令

    Linux之进程的虚拟地址空间 在Linux中,每个进程都有自己的虚拟地址空间,它是进程独立的内存空间。虚拟地址空间是一个抽象的概念,它将进程的内存分为多个区域,每个区域有不同的用途和访问权限。 逻辑地址和物理地址 进程使用逻辑地址来访问内存,而不是直接使用物理地址。逻辑地址是相对于进程的虚拟地址空间的地址,它是进程可见的地址。当进程访问逻辑地址时,操作系统…

    other 2023年8月2日
    00
  • springBoot解决static和@Component遇到的bug

    Spring Boot解决Static和@Component遇到的Bug攻略 在使用Spring Boot开发应用程序时,有时会遇到Static资源和@Component注解的一些常见问题。这些问题可能导致静态资源无法正确加载或@Component注解无法正常工作。下面是解决这些问题的完整攻略。 问题1:Static资源无法加载 问题描述 当使用Spring…

    other 2023年8月6日
    00
  • 强制在git中进行合并的最佳方法是什么?

    以下是关于“强制在Git中进行合并的最佳方法是什么?”的完整攻略,过程中包含两个示例。 背景 在Git中,有时需要强制进行合并。本攻略将介绍如何在Git中强制进行合并的最佳方法。 基本原理 在Git中,强制进行合并的最佳方法是使用–allow-unrelated-histories选项。该选项允许合并两个没有共同祖先的分支。具体步骤如下: 切换到目标分支。…

    other 2023年5月9日
    00
  • 一篇文章带你掌握C++虚函数的来龙去脉

    一篇文章带你掌握C++虚函数的来龙去脉 背景 C++中的虚函数是一个较为复杂的概念,但又是一个非常重要的特性。在C++中,新手程序员非常容易出现“虚函数”与“普通函数”的混淆,不理解其来龙去脉,导致代码出现各种问题。本篇文章将系统地介绍C++虚函数的基础知识,包括虚函数的用途,实现原理,虚函数表,以及多重继承等问题,帮助读者全面掌握C++虚函数的来龙去脉。 …

    other 2023年6月26日
    00
  • 详解Python读取配置文件模块ConfigParser

    下面是关于“详解Python读取配置文件模块ConfigParser”的详细攻略: 1. 什么是ConfigParser模块? ConfigParser是Python标准库中的一个模块,它用于读取和写入配置文件,是一种常见的Python配置方案。 在Python 2.x 版本中,ConfigParser是以 ConfigParser 包的形式存在;而在 Py…

    other 2023年6月25日
    00
  • Win10 Mobile商店终将加入最后更新日期、应用版本号

    Win10 Mobile商店终将加入最后更新日期、应用版本号攻略 介绍 Win10 Mobile商店是Windows 10 Mobile操作系统上的应用商店,用于下载和安装应用程序。最近,Win10 Mobile商店宣布将在未来的更新中加入最后更新日期和应用版本号的功能。这将使用户能够更好地了解应用程序的更新情况和版本信息。本攻略将详细介绍如何使用这些新功能…

    other 2023年8月3日
    00
  • 利用DNSLog实现无回显注入

    利用 DNSLog 实现无回显注入 在网络安全领域,无回显(Blind)注入攻击是一种常见的攻击方式。相比于普通的注入攻击,无回显注入攻击更难被发现和防范。为了利用这种攻击方式,黑客们常常会使用 DNSLog 工具进行控制和取数据。在本文中,我们将介绍如何使用 DNSLog 实现无回显注入攻击。 什么是 DNSLog DNSLog 是一款开源的,基于 DNS…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部