java版数据结构:深入理解栈和队列:数据结构与应用(vector,stack,queue)

目录

前言

动态数组类(vector)

特点:

应用:

栈(Stack)

栈的基础概念:

栈的常用方法:

模拟栈操作:

队列(Queue)

队列的基础概念

队列的常用方法

双端队列(Deque)

双端队列的基础概念:

双端队列的常用方法:

结语


前言

               在计算机科学中,栈(Stack)和队列(Queue)是两种常见的数据结构,它们在算法和程序设计中扮演着重要的角色。本文将深入探讨栈和队列的概念、使用方法以及相关的应用场景。


动态数组类(vector)

Vector是Java中的一个动态数组类,它实现了一个可增长的对象数组。与普通数组相比,Vector具有以下特点:

特点:

  1. 动态增长:Vector可以根据需要动态增长或缩小其大小,无需手动管理数组大小。
  2. 线程安全:Vector是线程安全的,即可以在多线程环境下使用,但由于同步操作的开销较大,通常不推荐在单线程环境下使用。
  3. 元素访问:可以通过索引访问Vector中的元素,也可以通过迭代器遍历Vector中的元素。
  4. 实现了List接口:Vector实现了List接口,因此支持列表操作,如添加、删除、获取元素等。
  5. 遗留类:Vector是Java早期的遗留类,通常不推荐在新代码中使用。在现代Java中,更推荐使用ArrayListLinkedList等更高效的集合类。

应用:

import java.util.Vector;

public class VectorExample {
    public static void main(String[] args) {
        // 创建一个Vector对象
        Vector<Integer> vector = new Vector<>();

        // 添加元素到Vector
        vector.add(1);
        vector.add(2);
        vector.add(3);

        // 输出Vector的大小
        System.out.println("Vector的大小: " + vector.size());

        // 获取指定位置的元素
        System.out.println("第二个元素: " + vector.get(1));

        // 修改指定位置的元素
        vector.set(0, 10);

        // 移除指定位置的元素
        vector.remove(2);

        // 检查Vector是否包含某个元素
        if (vector.contains(2)) {
            System.out.println("Vector包含元素2");
        } else {
            System.out.println("Vector不包含元素2");
        }

        // 清空Vector
        vector.clear();

        // 检查Vector是否为空
        if (vector.isEmpty()) {
            System.out.println("Vector为空");
        } else {
            System.out.println("Vector不为空");
        }
    }
}

运行结果: 


栈(Stack)

栈的基础概念:

         栈(Stack)是一种特殊的线性数据结构,具有后进先出(LIFO)的特性,即最后入栈的元素最先出栈。栈的操作主要包括压栈(push)、出栈(pop)、获取栈顶元素(peek)、获取栈中元素个数(size)以及检测栈是否为空(empty)等。

栈的常用方法:

  • 创建栈对象:
  1. 使用Stack类:可以直接使用Java提供的Stack类来创建栈对象,该类继承自Vector类,提供了压栈、出栈、获取栈顶元素等方法。
  2. 使用自定义栈类:也可以自定义栈类,通过数组或链表实现栈结构,实现压栈、出栈、获取栈顶元素等操作。
  • 基本操作方法:
  1. push(E e): 将元素压入栈顶。
  2. pop(): 弹出栈顶元素。
  3. peek(): 获取栈顶元素但不弹出。
  4. size(): 获取栈中元素个数。
  5. empty(): 检测栈是否为空。
import java.util.Stack;

public class StackExample {
    public static void main(String[] args) {
        // 创建一个栈对象
        Stack<Integer> stack = new Stack<>();

        // 压栈操作
        stack.push(1);
        stack.push(2);
        stack.push(3);

        // 输出栈的大小
        System.out.println("栈的大小: " + stack.size());

        // 获取栈顶元素
        System.out.println("栈顶元素: " + stack.peek());

        // 出栈操作
        stack.pop();
        System.out.println("出栈元素: " + stack.pop());
        //说明输出(出栈元素)的时候,是先打印原来的栈顶元素然后再出栈
        
        System.out.println("重新获得栈顶元素:"+stack.peek());

        // 检查栈是否为空
        if (stack.empty()) {
            System.out.println("栈为空");
        } else {
            System.out.println("栈的大小: " + stack.size());
        }
    }
}

运行结果: 

模拟栈操作:

  1. main方法中模拟栈的操作,包括压栈、出栈、获取栈顶元素、检测栈是否为空等操作。
  2. 可以使用Java提供的Stack类或自定义的栈类进行模拟操作。
import java.util.Arrays;

public class MyStack {
    int[] array;
    int size;

    public MyStack() {
        array = new int[3];
    }

    public int push(int e) {
        ensureCapacity();
        array[size++] = e;
        return e;
    }

    public int pop() {
        int e = peek();
        size--;
        return e;
    }

    public int peek() {
        if (empty()) {
            throw new RuntimeException("Stack is empty, cannot get top element");
        }
        return array[size - 1];
    }

    public int size() {
        return size;
    }

    public boolean empty() {
        return size == 0;
    }

    private void ensureCapacity() {
        if (size == array.length) {
            array = Arrays.copyOf(array, size * 2);
        }
    }
}

  • 应用场景:

    1. 改变元素的序列:通过栈可以实现元素序列的逆序。
    2. 将递归转化为循环:使用栈可以将递归算法转化为迭代算法。
    3. 括号匹配:栈常用于检测括号是否匹配。
    4. 逆波兰表达式求值:栈可以用于求解逆波兰表达式的值。
    5. 出栈入栈次序匹配:栈可以用于检测出栈入栈次序是否匹配。
    6. 最小栈:实现一个支持常数时间内获取栈中最小元素的栈。

队列(Queue)

队列的基础概念

      队列是另一种特殊的线性表,只允许在一端进行插入数据操作,在另一端进行删除数据操作。队列遵循先进先出(FIFO)的原则,即最先入队列的元素最先出队列。在Java中,Queue是一个接口,常通过LinkedList实现。队列的模拟实现可以使用顺序结构或链式结构。

      除了普通队列,还有循环队列的概念。循环队列通常使用数组实现,通过特定的下标循环技巧来实现队列的操作。设计循环队列时需要考虑空与满的情况,可以通过添加size属性、保留一个位置或使用标记来实现。

队列的常用方法

import java.util.LinkedList;
import java.util.Queue;

public class Main {
    public static void main(String[] args) {
        // 创建一个队列
        Queue<String> queue = new LinkedList<>();

        // 向队列中添加元素
        queue.offer("元素1");
        queue.offer("元素2");
        queue.offer("元素3");

        // 输出队列中的元素
        System.out.println("当前队列中的元素为:");
        for (String element : queue) {
            System.out.println(element);
        }

        // 出队操作
        String firstElement = queue.poll();
        System.out.println("出队的元素为:" + firstElement);

        // 查看队首元素
        String peekElement = queue.peek();
        System.out.println("当前队首元素为:" + peekElement);

        // 判断队列是否为空
        boolean isEmpty = queue.isEmpty();
        System.out.println("队列是否为空:" + isEmpty);

        // 获取队列大小
        int size = queue.size();
        System.out.println("当前队列大小为:" + size);
    }
}

运行结果: 

 


双端队列(Deque)

双端队列(Deque,全称Double-Ended Queue)是一种具有两端插入和删除操作的数据结构,它同时具备队列和栈的特性。双端队列可以在队列的两端进行元素的插入和删除操作,因此可以高效地支持在队列头部和尾部进行操作。

双端队列的基础概念:

  1. 两端操作:双端队列支持在队列的两端进行操作,即可以在队列的头部和尾部同时进行插入和删除操作。这使得双端队列既可以作为队列使用(先进先出),也可以作为栈使用(后进先出)。

  2. 插入和删除操作:双端队列提供了插入和删除元素的方法,如在队列头部插入元素、在队列尾部插入元素、在队列头部删除元素、在队列尾部删除元素等操作。

  3. 灵活性:双端队列的灵活性使得它在很多场景下都非常有用,比如需要同时支持队列和栈操作的情况,或者需要在队列的两端频繁进行操作的情况。

  4. 实现方式:双端队列可以通过数组、链表等数据结构来实现。在Java中,Deque接口定义了双端队列的基本操作,而LinkedListArrayDeque等类提供了Deque接口的实现。

双端队列的常用方法:

import java.util.ArrayDeque;
import java.util.Deque;

public class Main {
    public static void main(String[] args) {
        // 创建一个双端队列
        Deque<String> deque = new ArrayDeque<>();

        // 在队列头部插入元素
        deque.addFirst("元素1");
        deque.addFirst("元素2");

        // 在队列尾部插入元素
        deque.addLast("元素3");

        // 输出双端队列中的元素
        System.out.println("当前双端队列中的元素为:");
        for (String element : deque) {
            System.out.println(element);
        }

        // 在队列头部删除元素
        String firstElement = deque.removeFirst();
        System.out.println("删除的队列头部元素为:" + firstElement);

        // 在队列尾部删除元素
        String lastElement = deque.removeLast();
        System.out.println("删除的队列尾部元素为:" + lastElement);

        // 查看双端队列头部元素
        String peekFirstElement = deque.peekFirst();
        System.out.println("当前双端队列头部元素为:" + peekFirstElement);

        // 查看双端队列尾部元素
        String peekLastElement = deque.peekLast();
        System.out.println("当前双端队列尾部元素为:" + peekLastElement);
    }
}

 运行结果:


结语

          栈和队列作为常见的数据结构,在算法和程序设计中有着重要的应用。通过深入理解栈和队列的概念、使用方法以及相关应用场景,我们可以更好地应用它们解决实际问题。同时,掌握循环队列和双端队列的概念也能够拓展我们对数据结构的认识,提高编程效率和代码质量。

希望本文能够帮助读者更好地理解和运用栈和队列,为日后的算法学习和程序设计提供帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/589162.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VS Code工具将json数据格式化

诉求&#xff1a;json数据格式化应该在工作中用到的地方特别多&#xff0c;为了更方便、更仔细的对json数据查看&#xff0c;将json数据格式化是非常有必要的。 VS Code中如何将json数据快速格式化 1、在VS Code中安装Beautify JSON插件 2、安装完后在需要格式化的文件中按住…

Easy TCP Analysis上线案例库功能,为用户提供一个TCP抓包分析案例分享学习的平台

​案例库&#xff0c;提供给用户相互分享TCP抓包故障排查案例或是经典学习案例的功能&#xff0c;任何用户都可从案例库查看其它用户分享的案例&#xff0c;每个用户也都可以上传自己的案例&#xff0c;经过平台审核去重即可展示在案例库。 对于学习&#xff0c;最典型的三次握…

Linux进程概念(下)

Linux进程概念 1. 命令行参数2. 环境变量2.1 环境变量的概念2.2 环境变量的使用和一些问题2.3 获取环境变量2.4 深入理解环境变量2.5 环境变量相关的命令 3. 进程地址空间3.1 基本概念3.2 为什么要有地址空间 1. 命令行参数 main函数也可以带参数的&#xff0c;如下 #include…

Linux内核之原子操作:atomic_long_dec用法实例(六十七)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

2023-2024年汽车行业报告/方案合集(精选345份)

汽车行业报告/方案&#xff08;精选345份&#xff09; 2023-2024年 来源&#xff1a;2023-2024年汽车行业报告/方案合集&#xff08;精选345份&#xff09; 【以下是资料目录】 2023中国汽车科技50强 2023中国智能汽车产业发展与展望 2023比亚迪海豹汽车拆解报告 2023新能…

PotatoPie 4.0 实验教程(31) —— FPGA实现摄像头图像高斯滤波

什么是高斯滤波 高斯滤波是一种常见的图像处理技术&#xff0c;用于去除图像中的噪声和平滑图像。它的原理基于统计学中的高斯分布&#xff08;也称为正态分布&#xff09;。 在高斯滤波中&#xff0c;一个二维的高斯核函数被用来对图像中的每个像素进行加权平均。这个高斯核…

【沉淀之华】从0到1实现用户推荐 - 实时特征系统构建,包含特征计算,特征存储,特征查询,特征补偿超详细思路分享

文章目录 背景介绍设计初衷基本概念 技术架构"四高"特征存储特征计算特征查询特征补偿 技术难点Q&A彩蛋 背景介绍 设计初衷 作为用户推荐系统的支撑系统之一&#xff1a;用户实时特征系统有着举足轻重的重要&#xff0c;甚至说它是一起推荐行为触发的必要条件。…

【经典算法】LeetCode 160. 相交链表(Java/C/Python3/Go实现含注释说明,Easy)

目录 题目描述思路及实现方式一&#xff1a;哈希表思路代码实现Java版本C语言版本Python3版本Golang版本 复杂度分析 方式二&#xff1a;双指针思路代码实现Java版本C语言版本Python3版本Golang版本 复杂度分析 总结相似题目 标签(题目类型)&#xff1a;链表 题目描述 给你两…

C语言——操作符保姆级教学(含整形提升及算数转换)

操作符 一.操作符的分类二.原码、反码、补码三.移位操作符1.左移操作符&#xff1a;<<2.右移操作符&#xff1a;>> 四.位操作符1.按位与—— &2.按位或—— |3.按位异或—— ^4.按位取反—— ~ 五.逗号表达式六.条件操作符七.操作符的属性&#xff1a;优先级、…

如何配置和使用Apollo的component里的plugin

关于如何使用Apollo的Component里的plugin&#xff0c;在Apollo的文档里只有如果和开发的说明却没有找到一个清楚完整说明怎么把plugin跑起来的说明&#xff0c;例如我想把lidar_detection_filter按我们的需求对目标过滤算法作修改然后编译完后&#xff0c;执行 cyber_launch …

【数据结构】链表专题3

前言 本篇博客我们继续来讨论链表专题&#xff0c;今天的链表算法题是经典中的经典 &#x1f493; 个人主页&#xff1a;小张同学zkf ⏩ 文章专栏&#xff1a;数据结构 若有问题 评论区见&#x1f4dd; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 目录 1.判断链表是否…

Dom获取属性操作

目录 1. 基本认知 1.1 目的和内容 1.2 什么是DOM 1.3 DOM对象 1.4 DOM树 2. 获取DOM元素对象 2.1 选择匹配到的第一个元素 2.2 选择匹配到的多个元素 2.3 其他获取DOM元素方法 3. 操作元素内容 3.1 元素对象.innerText 属性 3.2 元素对象.innerHTML 属性 4. 操作元…

springcloud微服务搭建多数据源(mysql,oracle,postgres,等等)管理模块,支持通过注解方式切换不同类型的数据库

1.背景 同一套微服务管理系统&#xff0c;业务完全一样&#xff0c;但不同的客户可能要求使用自己熟悉的数据库&#xff0c;比如&#xff0c;mysql&#xff0c;oracle&#xff0c;postgres&#xff0c;还有一些国产数据库。如果能够将数据库模块独立出来&#xff0c;兼容各家的…

IDEA启动项目报错:Error running ‘‘: Command line is too long.

1、在workspace.xml 2、 在标签 <component name"PropertiesComponent"> 添加 <property name"dynamic.classpath" value"true" />

MySQL 运维篇

回顾基本语句&#xff1a; 数据定义语言(DDL) 这类语言用于定义和修改数据库的结构&#xff0c;包括创建、删除和修改数据库、 表、视图和索引等对象。 主要的语句关键字包括 CREATE 、 DROP 、 ALTER 、 RENAME 、 TRUNCATE 等。 create database 数据库 &#xff1b; cr…

【MySQL | 第十一篇】一条SQL语句在MySQL的执行过程

文章目录 11.一条SQL语句在MySQL的执行过程11.1MySQL整体架构11.2SQL语句在Server层执行流程11.3拓展&#xff1a;InnoDB存储引擎的更新操作11.3.1问题&#xff1a;为什么写了redolog日志还要写binlog日志&#xff1f;11.3.2问题&#xff1a;为什么要两阶段提交&#xff1f;11.…

《QT实用小工具·四十七》可交互的创意动态按钮

1、概述 源码放在文章末尾 该项目实现了可交互的创意动态按钮&#xff0c;包含如下功能&#xff1a; 所有颜色自定义 鼠标悬浮渐变 两种点击效果&#xff1a;鼠标点击渐变 / 水波纹动画&#xff08;可多层波纹叠加&#xff09; 额外鼠标移入/移出/按下/弹起的实时/延迟共8种事…

springboot 自动配置源码解读

什么是自动装配 当我们程序依赖第三方功能组件时&#xff0c;不需要手动将这些组件类加载到IOC容器中。例如 当程序需要用到redis时&#xff0c;在pom.xml文件中引入依赖&#xff0c;然后使用依赖注入的方式直接从IOC容器中拿到相应RedisTemplate实例。 SpringBootApplication …

【已解决】json文件太大无法打开怎么办+ijson报错

下载了一个json文档&#xff0c;尝试了全部的编辑器都打不开。。。 搜了搜或许可以使用ijson GitHub - ICRAR/ijson: Iterative JSON parser with Pythonic interfaces "Ijson is an iterative JSON parser with standard Python iterator interfaces." 示例代码&…

【C++ —— 多态】

C —— 多态 多态的概念多态的定义和实现多态的构成条件虚函数虚函数的重写虚函数重写的两个例外协变&#xff1a;析构函数的重写 C11 override和final重载、覆盖(重写)、隐藏(重定义)的对比 抽象类概念接口继承和实现继承 多态的继承虚函数表多态的原理动态绑定和静态绑定 单继…