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

news2024/11/25 16:47:29

目录

前言

动态数组类(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);
    }
}

 运行结果:


结语

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

golang学习笔记(协程的基础知识)

golang的协程 协程是一种轻量级的线程&#xff0c;它可以实现并发执行的并行操作。协程是Go语言中的一个核心特性&#xff0c;它使得程序能够以并发的方式运行&#xff0c;并且非常高效。与传统的线程相比&#xff0c;协程的创建和销毁成本非常低&#xff0c;可以方便地启动大…

三维坐标点按剖面分类

一、写在前面 ①配套文件&#xff1a;根据剖面对三维坐标点&#xff08;X,Y,Z&#xff09;分类资源-CSDN文库 ②脱敏处理&#xff1a;蚀变数据已采用随机数生成覆盖 ③剖面坐标按顺序排列在“剖面坐标点.xlsx”文件中 二、3点确定空间中平面方程 原理&#xff1a; 设3点A&…

C++深度解析教程笔记2

C深度解析教程笔记2 第3课 - 进化后的 const 分析实验-C与C的const区别实验-C与C的const区别&const作用域 第4课 - 布尔类型和引用小结 本文学习自狄泰软件学院 唐佐林老师的 C深度解析教程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 第3课 - 进化后…

列转行(spark 与presto语法)

一、Presto 语法 原始数据&#xff1a; 期望数据&#xff1a; 代码&#xff1a; SELECT info, value FROM ( select 张三 as name,18 as age,男 as gender,清华 as schoolunion allselect 李四 as name,18 as age,男 as gender,清华 as school ) as a CROSS JOIN UNNEST(…

Unreal 编辑器工具 批量重命名资源

右键 - Editor Utilities - Editor Utility Blueprint&#xff0c;基类选择 Asset Action Utility 在类默认值内&#xff0c;可以添加筛选器&#xff0c;筛选指定的类型 然后新建一个函数&#xff0c;加上4个输入&#xff1a;ReplaceFrom&#xff0c;ReplaceTo&#xff0c;Add…

使用Android Studio 搭建AOSP FrameWork 源码阅读开发环境

文章目录 概述安装Android Studio编译源码使用Android Studio打开源码制作ipr文件直接编译成功后自动打开Android Studio 修改SystemUI验证开发环境 概述 我们都知道Android的系统源码量非常之大&#xff0c;大致有frameworka层源码&#xff0c;硬件层(HAL)源码&#xff0c;内…

机器学习笔记-18

异常检测问题 异常检测虽然主要用于无监督学习问题上&#xff0c;但是和监督学习问题很相似。 异常检测(Anomaly Detection)&#xff1a;给定正确样本集{ x ( 1 ) , x ( 2 ) . . . x ( n ) x^{(1)},x^{(2)}...x^{(n)} x(1),x(2)...x(n)}&#xff0c;记新样本即要检测的样本为…

堆排序以及TOP-K问题

片头 嗨&#xff01;小伙伴们&#xff0c;大家好&#xff01;今天我们来深入理解堆这种数据结构&#xff0c;分析一下堆排序以及TOP-K问题&#xff0c;准备好了吗&#xff1f;我要开始咯&#xff01; 一、堆排序 这里我们先假设要排成升序&#xff0c;也就是从左到右&#xf…

JSP简介——[JSP]1

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;大大会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

基于php+mysql+html图书管理系统(含实训报告)

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、Php、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

【C++】命名冲突了怎么办?命名空间来解决你的烦恼!!!C++不同于C的命名方式——带你认识C++的命名空间

命名空间 导读一、什么是C?二、C的发展三、命名空间3.1 C语言中的重名冲突3.2 什么是命名空间&#xff1f;3.3 命名空间的定义3.4 命名空间的使用环境3.5 ::——作用域限定符3.6 命名空间的使用方法3.6.1 通过作用域限定符来指定作用域3.6.2 通过关键字using和关键字namespace…

如何用 Redis 实现延迟队列?

延迟队列是一种常见的消息队列模式&#xff0c;用于处理需要延迟执行的任务或消息。Redis 是一种快速、开源的键值对存储数据库&#xff0c;具有高性能、持久性和丰富的数据结构&#xff0c;因此很适合用于实现延迟队列。在这篇文章中&#xff0c;我们将详细讨论如何使用 Redis…

51单片机两个中断及中断嵌套

文章目录 前言一、中断嵌套是什么&#xff1f;二、两个同级别中断2.1 中断运行关系2.2 测试程序 三、两个不同级别中断实现中断嵌套3.1 中断运行关系3.2 测试程序 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 课程需要&#xff1a; 提示&#x…

Mysql基础(四)DML之insert语句

一 insert 语句 强调&#xff1a; 本文介绍的内容很基础,仅做记录用,参考价值较少 ① 总述 目的&#xff1a; 增加rows记录1、完整格式insert [into] 表名[字段名1[, 字段名2]] value[s](值1, 值2);备注&#xff1a;指定部分字段添加,没有被指定的字段要么会自动增长,要…

微信小程序demo-----制作文章专栏

前言&#xff1a;不管我们要做什么种类的小程序都涉及到宣传或者扩展其他业务&#xff0c;我们就可以制作一个文章专栏的页面&#xff0c;实现点击一个专栏跳转到相应的页面&#xff0c;页面可以有科普类的知识或者其他&#xff0c;然后页面下方可以自由发挥&#xff0c;添加联…

ensp 配置s5700 ssh登陆

#核心配置 sys undo info-center enable sysname sw1 vlan 99 stelnet server enable telnet server enable int g 0/0/1 port lin acc port de vlan 99 q user-interface vty 0 4 protocol inbound ssh authentication-mode aaa q aaa local-user admin0 password cipher adm…

结构分析的有限元法及matlab实现(徐荣桥)|【PDF教材+配套案例Matlab源码】

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

为何数据库推荐将IPv4地址存储为32位整数而非字符串?

目录 一、IPv4地址在数据库中的存储方式&#xff1f; 二、IPv4地址的存储方式比较 &#xff08;一&#xff09;字符串存储 vs 整数存储 &#xff08;二&#xff09;IPv4地址"192.168.1.8"说明 三、数据库推荐32位整数存储方式原理 四、存储方式对系统性能的影响…

服务器IP选择

可以去https://ip.ping0.cc/查看IP的具体情况 1.IP位置--如果是国内用&#xff0c;国外服务器的话建议选择日本&#xff0c;香港这些比较好&#xff0c;因为它们离这里近&#xff0c;一般延时低&#xff08;在没有绕一圈的情况下&#xff09;。 不过GPT的话屏蔽了香港IP 2. 企…

C++ | Leetcode C++题解之第64题最小路径和

题目&#xff1a; 题解&#xff1a; class Solution { public:int minPathSum(vector<vector<int>>& grid) {if (grid.size() 0 || grid[0].size() 0) {return 0;}int rows grid.size(), columns grid[0].size();auto dp vector < vector <int>…