# 深入浅出 快速认识JAVA常用数据结构【栈, 队列, 链表, 数组】

快速认识JAVA常用数据结构【栈, 队列, 链表】

前言 什么是数据结构

一种用来存储和组织数据的方法,描述了数据之间的关系和操作方式。通过合理选择和使用数据结构,可以大幅提高程序的运行效率存储效率以及代码可维护性

数据结构的重要性

数据结构决定了数据的存储和访问方式。选择合适的数据结构可以:

  • 优化性能:降低时间复杂度和空间复杂度。

    • 时间复杂度是什么

      • 代码进入数据结构计算阶段 (算法执行) 的运行时间和 数据规模 的增长关系,
        简单来说就是 随数据规模增长的运行时间
    • 空间复杂度是什么

      • 代码进入数据结构计算阶段 (算法执行) 的运行所需额外内存空间随数据规模的变化关系。
        简单来说就是 随数据规模增长的额外内存空间
  • 提高操作效率:快速查找、插入、删除等操作,可以显著提升程序的执行速度。

  • 解决复杂问题:数据结构在java中相当于一套为算法逻辑设计的高效 API,提供基础操作(如插入、删除、查找等)来支撑复杂问题的解决。

常见数据结构

1. 栈 (Stack)

  • 定义与特性
    栈是一种遵循 先进后出 原则的线性数据结构。它限制了数据的访问方式,只能在一端(栈顶)进行插入和删除操作,类似“弹匣装子弹”的过程。最后装的子弹最先射出

    • 栈顶:新数据从栈顶进入,称为“进栈”。
    • 栈底:当数据被移除时,从栈顶弹出,称为“弹栈”。
  • 应用场景

    1. 函数调用:栈用于存储函数的调用顺序及其局部变量。
    • 局部变量与栈的关系
      前置知识 : 什么是栈帧
      函数调用时在栈中分配的一块内存区域,用于存储该函数的运行 状态, 和函数信息 (参数, 局部变量, 返回地址, 其他状态… )

      1. 每次函数调用会分配一个栈帧,其中包含该函数的局部变量、参数和返回地址等信息。

      2. 局部变量是在函数的作用域内分配的,生命周期跟随函数的调用过程——调用开始时创建,调用结束后在栈中被释放。

      3. 等待被使用

        • 栈中存储的局部变量和状态,并不直接“运行”,而是为当前函数提供“可用的环境”。
        • 如果当前函数调用另一个函数,当前函数的栈帧会 暂时被挂起(停止运行),直到被调用的函数执行完成后,当前函数暂停状态恢复并继续执行。
    1. 表达式求值 (自行拓展):用于实现中缀表达式转后缀表达式的计算。

    中缀表达式转后缀表达式 缀 : 运算符

    ​ 像 3 + 4 * 5 就属于中缀表达式, 需要考虑运算符优先级和括号,计算复杂。
    ​ 通过栈,可以把中缀表达式转换成后缀表达式(如 3 4 5 * +),计算更简 单。

    为什么?

    • 后缀表达式规则:

      • 从左到右扫描,遇到数字就压入栈。

      • 遇到操作符时,从栈中弹出 最近压入的两个数字 进行计算,再将结果压入栈。

    • 计算步骤:

      • 表达式:3 4 5 * +

      • 初始化一个空栈。

      开始计算

      1. 遇到 3,数字,压入栈。
        栈:[3]

      2. 遇到 4,数字,压入栈。
        栈:[3, 4]

      3. 遇到 5,数字,压入栈。
        栈:[3, 4, 5]

      4. 遇到 *,是操作符:

        • 从栈中弹出 54,计算 4 * 5 = 20

        • 将结果 20 压入栈。
          栈:[3, 20]

      5. 遇到 +,是操作符:

        • 从栈中弹出 203,计算 3 + 20 = 23

        • 将结果 23 压入栈。
          栈:[23]

    1. 浏览器回退与前进:通过两个栈实现页面的前进和后退功能。
  • **图示 **:

    栈结构图解:
    ┌─────────┐│   数据4  	  栈顶(Top) ← 从这里进栈(Push)├─────────┤  │   数据3  │  	  ├─────────┤  │   数据2  │  	  ├─────────┤  │   数据1  │        └─────────┘栈底(Bottom)
    
    关键操作说明
    1. 进栈 (Push)

      • 将数据压入栈中,新数据总是位于栈顶。
      • 图示:
        进栈 数据5:┌─────────┐│   数据5    ← 新栈顶├─────────┤│   数据4  │	├─────────┤│   数据3  │	├─────────┤│   数据2  └─────────┘
        
    2. 弹栈 (Pop)

      • 从栈顶移除数据,弹出的数据是最后压入的数据。
      • 图示:
        弹栈 数据5:┌─────────┐│   数据4    ← 新栈顶├─────────┤│   数据3 │├─────────┤│   数据2 │└─────────┘
        
    3. 函数调用栈

      函数A 调用 函数B,函数B调用 函数C:
      ┌─────────┐
      │ 函数C局部   ← 当前执行
      ├─────────┤
      │ 函数B局部│
      ├─────────┤
      │ 函数A局部│
      └─────────┘
      

队列 (Queue)

  • 介绍
    队列是一种遵循 先进先出 原则的线性数据结构,数据只能从队尾插入,从队头取出,类似排队买票的过程。

    • 入队:数据从队尾进入。
    • 出队:数据从队头移出。
  • 存储顺序

    • 数据顺序存储

    • 新数据从队尾加入

    • 旧数据从队头取出
      这种方式保证了数据处理的顺序性和公平性。

      队头                 队尾  ↓                   ↓  
      [1] -> [2] -> [3] -> [4]  ↑  取出  
      

数组 (Array)

定义与特性
数组是一种基于连续内存空间的线性数据结构,其中每个元素通过索引直接访问。所 有元素共享相同的内存地址偏移量,存取速度快。

示例:

数组:  A   B   C   D   E   F   G  
索引:  0   1    2   3    4  5    6  
  • 优点

    1. 快速访问
      • 通过索引直接访问元素,时间复杂度为 O(1) -> 直接访问。
    2. 数据独立性
      • 每个元素在数组中独立存在,无需依赖其他元素,方便管理和操作。
  • 缺点

    1. 插入和删除效率低
      • 需要移动大量元素,时间复杂度为 O(n) -> 一次操作多次移动元素位置。
    2. 固定大小
      • 数组长度在初始化时需要确定,后期无法动态扩展。

  • 应用场景

    1. 频繁查找的场景

      • 如哈希表的底层存储,利用数组的快速索引特性。

优化后的图表:

优点描述
快速访问支持通过索引直接访问,效率高 O(1)。
数据独立性每个元素独立存在,操作简单,不依赖其他元素。
缺点描述
插入效率低需要移动元素,插入和删除操作成本高 O(n)。
固定大小初始化后长度固定,扩展性差,无法灵活调整容量。

结构图示:

数组:  A   B   C   D   E   F   G  
索引:  0   1   2   3   4   5   6  插入操作(在索引3处插入X):  
移动后的数组:  A   B   C   X   D   E   F   G  

链表(Linked List)

  • 介绍
    链表是一种由节点构成的线性数据结构,每个节点包含以下两部分

    • 数据域:存储节点自身的数据。

    • 指针域:存储下一个节点(或前后节点)的地址。

分类
类型特性
单向链表每个节点只包含一个指向下一个节点的指针。
双向链表每个节点包含两个指针,分别指向前一个节点和后一个节点。
循环链表最后一个节点的指针指向第一个节点,形成闭环结构。
优点
  1. 动态扩展:链表不需要连续的内存空间,内存利用率高。
  2. 高效插入与删除:仅需修改指针即可完成操作,无需移动数据,效率高。
缺点
  1. 查询效率低:链表无法通过索引直接访问,需要从头逐一遍历,耗时较多。
  2. 额外存储开销:需要额外的指针域存储地址,占用更多内存。
图示
  1. 单向链表

    [数据 | 指针] -> [数据 | 指针] -> [数据 | 指针] -> NULL
    
  2. 双向链表

    NULL <- [指针 | 数据 | 指针] <-> [指针 | 数据 | 指针] <-> NULL
    
  3. 循环链表
    链式存储结构,链表的尾节点指向头节点,形成一个首尾相连的环状结构。根据节点指针的数量,循环链表可以分为以下两种类型:

    1. 单向循环链表:每个节点仅包含一个指针域,指向下一个节点,最后一个节点的指针回指到头节点。
    2. 双向循环链表:每个节点包含两个指针域,分别指向前一个节点和后一个节点,头节点和尾节点通过指针互相连接。

    特点:

    • 可以从任意节点开始访问整个链表。

    优点: 高效利用尾节点与头节点的连接,无需特殊处理末尾条件。
    缺点: 实现和维护较普通链表复杂。

总结

链表在灵活性和动态扩展方面具有显著优势,但查询效率较低,不过频繁插入和删除的场景中表现较好。

总结

  • 查询频繁,数据量较小:优先选择数组,支持快速访问。
  • 插入和删除频繁:优先选择链表,避免大量数据移动。
  • 队列场景:需要依赖先进先出的规则时使用队列。

如果这篇文章帮到你, 帮忙点个关注呗, 点赞或收藏也行鸭 ~ (。•ᴗ-)✧

在这里插入图片描述
^ '(இ﹏இ`。)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

负载均衡OJ项目中遇到的问题

1、续行符问题 关于换行符 &#xff0c;代码在使用了换行符后无法编译文件&#xff0c;也没有爆出任何错误&#xff0c;更没有按照我们的代码打印出如下类似内容 &#xff1a;[ERROR][compiler.hpp][66][1732635247]编译失败,没有形成可执行程序 随机排查才发现。 代码中的 \ …

android编译assets集成某文件太大更新导致git仓库变大

不知道大家有没有类似的困扰&#xff0c;你的工程assets文件过大&#xff0c;我曾经在某度车机地图团队工作过一段时间时候&#xff0c;每次发包会集成一个上百MB的文件。工作一段时间你的git仓库将会增加特别多。最后&#xff0c;你会发现你如果重新git clone这个仓库会非常大…

关闭windows11的“热门搜索”

win10搜索栏热门搜索怎么关闭&#xff1f;win10搜索栏热门搜索关闭方法分享_搜索_onecdll-GitCode 开源社区 注册表地址是&#xff1a;计算机\HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\ 最后效果如下&#xff1a;

【数字电路与逻辑设计】实验五 4人表决器

文章总览&#xff1a;YuanDaiMa2048博客文章总览 【数字电路与逻辑设计】实验五 4人表决器 一、实验内容二、设计过程&#xff08;一&#xff09;设置变量&#xff08;二&#xff09;真值表&#xff08;三&#xff09;表达式 三、源代码&#xff08;一&#xff09;代码说明&…

Yeeco成长型一体化数智赋能平台:科技矩阵重塑企业数字生态

随着科技的飞速发展&#xff0c;我们正在步入一个被称为“数智化时代”的新时代。在这个时代中&#xff0c;数据处理和分析的能力被提升到一个前所未有的高度&#xff0c;而这种变化背后的重要推动力量就是各种新兴的技术趋势。 为了在激烈的市场竞争中脱颖而出&#xff0c;Yee…

PlantUML——类图

背景 类图是UML模型中的静态视图&#xff0c;其主要作用包括&#xff1a; 描述系统的结构化设计&#xff0c;显示出类、接口以及它们之间的静态结构和关系。简化对系统的理解&#xff0c;是系统分析与设计阶段的重要产物&#xff0c;也是系统编码和测试的重要模型依据。 在U…

LabVIEW热阻炉温度控制

在工业自动化和控制系统领域&#xff0c;温度的精确控制对于保障生产过程的稳定性和产品质量非常重要。热阻炉作为一个典型的受控对象&#xff0c;其温度控制系统的设计和实现涉及多个技术层面&#xff0c;包括硬件选择、控制策略的设计以及软件的实现。项目使用LabVIEW软件开发…

MongoDB在自动化设备上的应用示例

发现MongoDB特别适合自动化检测数据的存储。。。 例如一个晶圆检测项目&#xff0c;定义其数据结构如下 #pragma once #include <vector> #include <QString> #include <QRectF> #include <string> #include <memory>class tpoWafer; class tp…

day04-产品原型-学习计划

1. 分析整体业务流程 2. 提交学习记录-接口 2.1 需求 在课程学习页面播放视频时或考试后&#xff0c;需要提交学习记录到服务器保存&#xff0c;如用户播放视频的进度、学过的章节等。 2.1 接口详情 请求方式&#xff1a;POST 请求路径&#xff1a;/learning-record 请求…

基于Matlab的卷积神经网络(CNN)苹果分级检测系统

本研究提出了一种基于卷积神经网络&#xff08;CNN&#xff09;的自动化苹果分级系统&#xff0c;该系统根据苹果的视觉特征进行分类。系统采用了预训练的深度学习模型&#xff0c;使用包含不同等级苹果的图像数据集进行训练。研究方法包括图像预处理、特征提取和苹果等级分类。…

MySQL内置函数学习

引言 MySQL内置函数是MySQL数据库系统提供的预定义函数&#xff0c;用于执行特定的操作&#xff0c;如数学计算、字符串处理、日期和时间操作等。这些函数极大地简化了SQL语句的编写&#xff0c;提高了数据库操作的效率。 MySQL内置函数分类 MySQL内置函数可以大致分为以下几…

小程序入门学习(四)之全局配置

一、 全局配置文件及常用的配置项 小程序根目录下的 app.json 文件是小程序的全局配置文件。常用的配置项如下&#xff1a; pages&#xff1a;记录当前小程序所有页面的存放路径 window&#xff1a;全局设置小程序窗口的外观 tabBar&#xff1a;设置小程序底部的 tabBar 效…

【Web】AlpacaHack Round 7 (Web) 题解

Treasure Hunt flag在md5值拼接flagtxt的文件里&#xff0c;如 d/4/1/d/8/c/d/9/8/f/0/0/b/2/0/4/e/9/8/0/0/9/9/8/e/c/f/8/4/2/7/e/f/l/a/g/t/x/t 访问已经存在的目录状态码是301 访问不存在的目录状态码是404 基于此差异可以写爆破脚本 这段waf可以用url编码绕过 做个lab …

android studio 读写文件操作(应用场景三)

android studio版本&#xff1a;2023.3.1 patch2 例程&#xff1a;filesaveandread 其实我写这个都是我记录我要做后个数独小游戏&#xff0c;每一个都是为了解决一个问题。即是分享也是备忘&#xff0c;反正我什么都不会&#xff0c;就是一顿瞎改&#xff0c;不行就研究。这…

c++:timer

1.设置休眠时间sleep_for 添加头文件 #include <thread> #include <iostream> #include <chrono> #include <thread>int main(int argc, char const *argv[]) {// 休眠2秒std::this_thread::sleep_for(std::chrono::seconds(2));// 休眠500毫秒std:…

【开源】A064—基于JAVA的民族婚纱预定系统的设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看项目链接获取⬇️&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600个选题ex…

嵌入式学习(17)-stm32F407串口使用注意事项

一、概述 配置串口时串口的接收一直不好使&#xff0c;对比例程发现了问题&#xff1a; 在网上也找了一些资料供参考“STM32F4的串口RX引脚不能被设置为输入是因为串口的接收&#xff08;RX&#xff09;功能是由硬件电路实现的&#xff0c;无法通过软件配置来控制。串口接收功…

如何在UI自动化测试中创建稳定的定位器?

如何在UI自动化测试中创建稳定的定位器&#xff1f; 前言1. 避免使用绝对路径2. 避免在定位器中使用索引3. 避免多个类名的定位器4. 避免动态和自动生成的ID5. 确保定位器唯一6. 处理隐藏元素的策略7. 谨慎使用基于文本的定位器8. 使用AI创建稳定的定位器 总结 前言 在自动化测…

在做题中学习(77):快排

解法&#xff1a;快排 思路&#xff1a; 1.快排排一趟&#xff0c;递归分出来的左区间和右区间&#xff08;一趟的思想&#xff0c;看我的前一个文章&#xff1a;颜色分类题解&#xff09; 2.递归&#xff1a;想清楚 函数头 和 返回条件怎么写 函数头&#xff1a;把递归想成…