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

news2024/12/22 18:05:13

快速认识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.coloradmin.cn/o/2255760.html

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

相关文章

fastadmin 后台插件制作方法

目录 一&#xff1a;开发流程 二&#xff1a;开发过程 &#xff08;一&#xff09;&#xff1a;后台功能开发 &#xff08;二&#xff09;&#xff1a;功能打包到插件目录 &#xff08;三&#xff09;&#xff1a;打包插件 &#xff08;四&#xff09;&#xff1a;安装插件…

使用Dapper创建一个简单的查询

1.先在NuGet上下载Dapper包 2.创建对应的model 代码如下&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 数据显示 {public class User{public int UserId { get; set; }public…

雨晨 2610(2)0.2510 Windows 11 24H2 Iot 企业版 LTSC 2024 极简 2in1

文件: 雨晨 2610(2)0.2510 Windows 11 24H2 Iot 企业版 LTSC 2024 极简 2in1 install.esd 索引: 1 名称: Windows 11 IoT 企业版 LTSC 极简 26100.2510 描述: Windows 11 IoT 企业版 LTSC 极简 26100.2510 By YCDISM RTM 2025 24-12-07 大小: 8,176,452,990 个字节 索引: 2 …

Kubernetes 深入浅出系列 | 容器编排与作业调度之Deployment

目录 概述Deployment 的更新原理实验 概述 Kubernetes 中&#xff0c;Deployment 控制器是用于管理应用程序生命周期的核心对象。Deployment 通过管理 ReplicaSet 来间接控制 Pod&#xff0c;确保在任何时刻都能维持指定数量的 Pod 副本。这种间接管理使得 Deployment 功能比 …

网络练级宝典-> UDP传输层协议

目录 传输层 端口号 端口号和进程的关系 UDP协议 UDP协议格式 UDP数据封装&#xff1a; UDP数据分用&#xff1a; 面向数据报 UDP的缓冲区 UDP的缺点 基于UDP的应用层协议 传输层 端口号 我们知道端口号对应的其实就是一个进程的pid&#xff0c;在操作系统中二者的…

Ubuntu22.04系统源码编译OpenCV 4.10.0(包含opencv_contrib)

因项目需要使用不同版本的OpenCV&#xff0c;而本地的Ubuntu22.04系统装了ROS2自带OpenCV 4.5.4的版本&#xff0c;于是编译一个OpenCV 4.10.0&#xff08;带opencv_contrib&#xff09;版本&#xff0c;给特定的项目使用&#xff0c;这就不用换个设备后重新安装OpenCV 了&…

获取联通光猫的管理员密码

缘起&#xff1a;联通给免费更换了一个新的光猫&#xff0c;烽火的光路由&#xff0c;一个WAN口&#xff0c;4个LAN口&#xff0c;带USB接口&#xff0c;欣欣然接受。但是呢&#xff0c;发现以前的管理员密码CUAdmin不能用了。经过一系列查询&#xff0c;借助别人的经验&#x…

残差网络连接,使得输入与输出的尺寸一样

def forward(self, x):out self.layer1(x)out self.layer2(out)# 使用插值将输入x上采样至与layer2输出相同的尺寸x F.interpolate(x, size(out.size(2), out.size(3)), modebilinear, align_cornersFalse)# 确保x的通道数与out匹配x x[:, :out.size(1), :, :] # 选择前ou…

计算机网络原理之HTTP与HTTPS

一、前言 为了理解HTTP&#xff0c;我们有必要事先了解一下TCP/IP协议簇。 通常我们使用的网络&#xff08;包括互联网&#xff09;是在TCP/IP协议簇的基础上运作的。而HTTP属于它内部的一个子集。 计算机与网络设备要相互通信&#xff0c;双方必须基于相同的方法。比如&#…

实验三:Mybatis-动态 SQL

目录&#xff1a; 一 、实验目的&#xff1a; 通过 mybatis 提供的各种标签方法实现动态拼接 sql 二 、预习要求&#xff1a; 预习 if、choose、 when、where 等标签的用法 三、实验内容&#xff1a; 根据性别和名字查询用户使用 if 标签改造 UserMapper.xml使用 where 标签进行…

NLP论文速读(斯坦福大学)|使用Tree将语法隐藏到Transformer语言模型中正则化

论文速读|Sneaking Syntax into Transformer Language Models with Tree Regularization 论文信息&#xff1a; 简介&#xff1a; 本文的背景是基于人类语言理解的组合性特征&#xff0c;即语言处理本质上是层次化的&#xff1a;语法规则将词级别的意义组合成更大的成分的意义&…

C++STL容器vector容器大小相关函数

目录 前言 主要参考 vector::size vector::max_size vector::resize vector::capacity vector::empty vector::reserve vector::shrink_to_fit 共勉 前言 本文将讨论STL容器vector中与迭代器相关的函数&#xff0c;模板参数T为int类型。 主要参考 cpluscplus.com 侯…

后端-编辑按钮的实现

编辑一共要实现两步&#xff1a; 1.点击编辑蹦出来一个弹窗&#xff0c;此时需要回显&#xff0c;根据id查出来这条数据 2.修改某些值之后点击保存的时候调用修改的接口 根据id查询的时候正常操作 修改值的时候要注意一些问题 mapper层的Employee和impl层的接收实体不一样

Spring Boot漫画之家:漫画爱好者的数字图书馆

2 系统开发环境 2.1 JAVA简介 JavaScript是一种网络脚本语言&#xff0c;广泛运用于web应用开发&#xff0c;可以用来添加网页的格式动态效果&#xff0c;该语言不用进行预编译就直接运行&#xff0c;可以直接嵌入HTML语言中&#xff0c;写成js语言&#xff0c;便于结构的分离&…

RISC-V 汇编语言

安装RISCV工具链 riscv-gnu-toolchain工具链和模拟器安装记录 - 知乎 (zhihu.com) riscv-gnu-toolchain工具链分elf-gcc、linux-gnu-gcc两个版本&#xff0c;以及对应的32位和64位版本。两个版本的主要区别是&#xff1a; riscv32-unknown-elf-gcc、riscv64-unknown-elf-gcc…

长沙市的科技查新机构有哪些

中南大学图书馆科技查新站&#xff1a; 中南大学图书馆科技查新站成立于2003年12月&#xff0c;中南大学图书馆科技查新站作为教育部首批批准的科技查新工作站之一&#xff0c;具备了在全国范围内开展科技查新工作的专业资质。 长沙理工大学科技查新工作站&#xff1a; 长沙理…

Spring Data Elasticsearch

简介说明 spring-data-elasticsearch是比较好用的一个elasticsearch客户端&#xff0c;本文介绍如何使用它来操作ES。本文使用spring-boot-starter-data-elasticsearch&#xff0c;它内部会引入spring-data-elasticsearch。 Spring Data ElasticSearch有下边这几种方法操作El…

【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 …

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

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

解决Tomcat运行时错误:“Address localhost:1099 is already in use”

目录 背景: 过程&#xff1a; 报错的原因&#xff1a; 解决的方法&#xff1a; 总结&#xff1a; 直接结束Java.exe进程&#xff1a; 使用neststat -aon | findstr 1099 命令&#xff1a; 选择建议&#xff1a; 背景: 准备运行Tomcat服务器调试项目时&#xff0c;程序下…