Java Deque队列讲解和案例示范

第一部分:Deque类概述

Deque的定义与特性

Deque(Double-Ended Queue)是一种双端队列,可以在两端高效地插入和删除元素。与Queue和Stack相比,Deque提供了更多的灵活性,因为它支持在两端进行操作。

  • 特性:
    • 支持在队列的两端插入和删除元素。
    • 可以作为队列和栈的实现。
    • 可以存储null元素(在某些实现中)。
Deque与Queue和Stack的区别
  • Queue:只允许在一端插入,在另一端删除,遵循先进先出(FIFO)原则。
  • Stack:只允许在一端插入和删除,遵循后进先出(LIFO)原则。
  • Deque:既可以在头部也可以在尾部插入和删除元素,提供了更多灵活性。

第二部分:Deque的常见方法讲解

Deque类提供了一系列常用方法来操作双端队列,以下是一些常见的方法及其示例:

1. 添加元素的方法
  • addFirst(E e):在队列的头部添加元素。
  • addLast(E e):在队列的尾部添加元素。
Deque<String> deque = new ArrayDeque<>();
deque.addFirst("商品1");
deque.addLast("商品2");
2. 移除元素的方法
  • removeFirst():移除并返回队列的头元素。
  • removeLast():移除并返回队列的尾元素。
String first = deque.removeFirst(); // 返回"商品1"
String last = deque.removeLast();   // 返回"商品2"
3. 访问元素的方法
  • getFirst():获取队列的头元素但不移除。
  • getLast():获取队列的尾元素但不移除。
String head = deque.getFirst(); // 返回"商品1"
String tail = deque.getLast();   // 返回"商品2"
4. 迭代器的使用

Deque还支持迭代器的使用,可以遍历所有元素。

for (String item : deque) {System.out.println(item);
}

第三部分:Deque的使用示例

1. 购物车管理

购物车可以被视为一个Deque,用户可以随时添加、删除商品。

Deque<Product> cart = new ArrayDeque<>();
cart.addLast(new Product("商品1", 100));
cart.addLast(new Product("商品2", 200));
cart.removeFirst(); // 移除第一个商品
2. 浏览历史管理

用户在电商平台上的浏览历史可以使用Deque来管理,支持快速访问和删除。

Deque<Page> history = new ArrayDeque<>();
history.addLast(new Page("首页"));
history.addLast(new Page("商品详情"));
history.removeFirst(); // 删除最旧的页面
3. 订单处理

在订单处理系统中,Deque可以用于管理待处理订单。

Deque<Order> orders = new ArrayDeque<>();
orders.addLast(new Order(1, "用户1"));
orders.addLast(new Order(2, "用户2"));
Order nextOrder = orders.removeFirst(); // 处理下一个订单

第四部分:Deque的底层实现

Java中的Deque实现类

Java标准库提供了几个Deque的实现,主要包括:

  1. ArrayDeque
    • 实现:基于动态数组,支持双端插入和删除。
    • 优点:相较于LinkedList,ArrayDeque在内存使用上更加高效,插入和删除操作通常更快。
    • 缺点:容量有限,当数组满时,需要进行扩容,扩容时会复制原数组,性能会受到影响。
  2. LinkedList
    • 实现:基于链表,支持任意数量的元素。
    • 优点:支持动态扩展,插入和删除操作在链表的任意位置都很高效。
    • 缺点:每个元素都需要额外的内存存储指针,因此在内存使用上不如ArrayDeque高效。
ArrayDeque与LinkedList的比较
特性ArrayDequeLinkedList
内存使用更少(动态数组)更多(每个节点额外指针)
插入/删除操作复杂度O(1)(平均情况下)O(1)
随机访问复杂度O(1)O(n)
扩容需要复制数组动态扩展
内存使用与性能分析
  • ArrayDeque:在大多数情况下,ArrayDeque由于内存连续,能够提供更好的缓存局部性,导致更快的访问速度。
  • LinkedList:虽然支持动态大小,但由于内存的非连续性,频繁的内存分配和垃圾回收会影响性能。

第五部分:Deque与算法问题

Deque在解决某些经典算法问题时非常有用,以下是几个具体问题的示例:

1. 滑动窗口最大值问题

问题描述:给定一个整数数组和窗口大小k,找到每个滑动窗口的最大值。

代码示范

import java.util.*;public class SlidingWindowMax {public int[] maxSlidingWindow(int[] nums, int k) {if (nums.length == 0) return new int[0];int[] result = new int[nums.length - k + 1];Deque<Integer> deque = new ArrayDeque<>();for (int i = 0; i < nums.length; i++) {// 移除不在窗口中的元素if (!deque.isEmpty() && deque.peekFirst() == i - k) {deque.pollFirst();}// 移除比当前元素小的所有元素while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {deque.pollLast();}deque.addLast(i);// 记录当前窗口的最大值if (i >= k - 1) {result[i - k + 1] = nums[deque.peekFirst()];}}return result;}public static void main(String[] args) {SlidingWindowMax swm = new SlidingWindowMax();int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};int k = 3;int[] result = swm.maxSlidingWindow(nums, k);System.out.println(Arrays.toString(result)); // 输出:[3, 3, 5, 5, 6, 7]}
}
2. 最小栈问题

问题描述:设计一个支持push、pop、top和retrieving the minimum element的栈。

代码示范

class MinStack {private Deque<Integer> stack;private Deque<Integer> minStack;public MinStack() {stack = new ArrayDeque<>();minStack = new ArrayDeque<>();}public void push(int x) {stack.addLast(x);// 如果当前元素小于或等于最小元素,更新最小栈if (minStack.isEmpty() || x <= minStack.peekLast()) {minStack.addLast(x);}}public void pop() {int value = stack.removeLast();// 如果弹出的是当前最小元素,更新最小栈if (value == minStack.peekLast()) {minStack.removeLast();}}public int top() {return stack.peekLast();}public int getMin() {return minStack.peekLast();}public static void main(String[] args) {MinStack minStack = new MinStack();minStack.push(5);minStack.push(3);minStack.push(7);System.out.println(minStack.getMin()); // 输出:3minStack.pop();System.out.println(minStack.getMin()); // 输出:3minStack.pop();System.out.println(minStack.getMin()); // 输出:5}
}
复杂度分析
  • 滑动窗口最大值问题:每个元素最多被添加和移除一次,因此时间复杂度为O(n),空间复杂度为O(k)。
  • 最小栈问题:所有操作的时间复杂度均为O(1),空间复杂度为O(n),因为存储了所有元素及其最小值。

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

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

相关文章

手机sd卡数据被清空怎么恢复原状?高效、可行的恢复策略

在数字化时代&#xff0c;手机SD卡作为我们存储重要数据的“数字仓库”&#xff0c;其安全性与稳定性直接关系到我们日常生活的便捷与信息安全。然而&#xff0c;不慎操作或系统故障导致的SD卡数据清空&#xff0c;常常让人措手不及&#xff0c;焦虑万分。面对这一挑战&#xf…

windows10或11家庭版实现远程桌面连接控制

远程协助是一种Windows工具&#xff0c;允许控制者使用鼠标和键盘远程控制接受者的计算机&#xff0c;从某种程度上讲&#xff0c;这也是Win10家庭版无法远程桌面的一个有效替代方案。 步骤1. 在使用Windows远程协助之前&#xff0c;您需要先更改某些设置&#xff0c;右键单击…

Pikichu-xss实验案例-通过xss获取cookie

原理图&#xff1a; pikachu提供了一个pkxss后台&#xff1b; 该后台可以把获得的cookie信息显示出来&#xff1b; 查看后端代码cookie.php&#xff1a;就是获取cookie信息&#xff0c;保存起来&#xff0c;然后重定向跳转到目标页面&#xff1b;修改最后从定向的ip&#xff0…

【C++】关键字+命名空间

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解C的命名空间&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 一. 关键字二. 命名空间2.1 命名空间的定义2.2 命名空间的使用a. 命名空间名称作用域限定…

source insight 的开源替代

source insight 的开源替代——sourcetrail&#xff0c;开源地址&#xff1a;https://github.com/CoatiSoftware/Sourcetrail Sourcetrail 是一个交互式源代码浏览器&#xff0c;它通过为代码编制索引并收集有关其结构的数据来简化现有源代码中的导航。然后&#xff0c;Sourcet…

【Linux的内存管理】

为什么需要内存管理 分段和分页内存分段内存分页 分页情况下&#xff0c;虚拟内存如何映射到物理地址页表原理多级页表 TLB快表段页式内存管理需要为什么进程地址空间Linux的进程虚拟地址空间管理进程地址空间如何分配虚拟内存虚拟内存的管理程序编译后的二进制文件如何映射到虚…

论文笔记:微表情欺骗检测

整理了AAAI2018 Deception Detection in Videos 论文的阅读笔记 背景模型实验可视化 背景 欺骗在我们的日常生活中很常见。一些谎言是无害的&#xff0c;而另一些谎言可能会产生严重的后果。例如&#xff0c;在法庭上撒谎可能会影响司法公正&#xff0c;让有罪的被告逍遥法外。…

TIM(Timer)定时器的原理

一、介绍 硬件定时器的工作原理基于时钟信号源提供稳定的时钟信号作为计时器的基准。计数器从预设值开始计数&#xff0c;每当时钟信号到达时计数器递增。当计数器达到预设值时&#xff0c;定时器会触发一个中断信号通知中断控制器处理相应的中断服务程序。在中断服务程序中&a…

启动redis

1. 进入root的状态&#xff0c;sudo -i 2. 通过sudo find /etc/redis/ -name "redis.conf"找到redis.conf的路径 3. 切换到/etc/redis目录下&#xff0c;开启redis服务 4. ps aux | grep redis命令查看按当前redis进程&#xff0c;发现已经服务已经开启 5.关闭服务…

【Linux】进程控制(创建、终止、等待、替换)

文章目录 1. 进程创建2. 进程终止3. 进程等待4. 进程程序替换4.1 认识进程替换4.2 认识全部接口 1. 进程创建 如何创建进程我们已经在之前学习过了&#xff0c;无非就是使用fork()&#xff0c;它有两个返回值。创建成功&#xff0c;给父进程返回PID&#xff0c;给子进程返回0&…

解决:使用layui.treeTable.updateNode,更新表格数据后,done里面的事件丢失问题

1. 背景 在给树形表格添加行点击事件&#xff0c;并且只更新当前行数据。 treeTable.updateNode("SpeProjListId", result.LAY_DATA_INDEX, result);更新数据后&#xff0c;点击事件失效。 1. 给字段绑定事件&#xff1a; class"link_a link_style" , {…

AI2.0时代,普通小白如何通过AI月入30万

最近这2年AI真的太火了&#xff0c;很多人都在讨论怎么用AI赚钱、提高效率。其实&#xff0c;我觉得AI并没有那么复杂&#xff0c;尤其是如果你不做AI底层研究&#xff0c;只是利用它来帮你省事、提效、赚钱&#xff0c;那就像当初学用电脑、用手机一样简单。你不需要懂AI的技术…

论文阅读:PET/CT Cross-modal medical image fusion of lung tumors based on DCIF-GAN

摘要 背景&#xff1a; 基于GAN的融合方法存在训练不稳定&#xff0c;提取图像的局部和全局上下文语义信息能力不足&#xff0c;交互融合程度不够等问题 贡献&#xff1a; 提出双耦合交互式融合GAN&#xff08;Dual-Coupled Interactive Fusion GAN&#xff0c;DCIF-GAN&…

Oracle 数据库安装和配置详解

Oracle 数据库安装和配置详解 Oracle 数据库是一款功能强大、广泛使用的企业级关系数据库管理系统 (RDBMS)&#xff0c;适用于处理大型数据库和复杂事务。本文将介绍如何在 Linux 和 Windows 环境下安装 Oracle 数据库&#xff0c;并对其进行基本配置&#xff0c;帮助开发者快…

国外电商系统开发-运维系统拓扑布局

点击列表中设备字段&#xff0c;然后定位到【拓扑布局】中&#xff0c;可以看到拓扑发生了变化 再回头&#xff0c;您再次添加一个服务器到系统中&#xff0c;并且选择该服务器的连接节点为您刚才创建的“SDN路由器”&#xff0c;保存后&#xff0c;您可以看到这个服务器连接着…

红帽操作系统Linux基本命令2( Linux 网络操作系统 06)

本文接着上篇Linux常用命令-1继续往后学习其他常用命令。 2.3 目录操作类命令 1&#xff0e;mkdir命令 mkdir命令用于创建一个目录。该命令的语法为&#xff1a; 上述目录名可以为相对路径&#xff0c;也可以为绝对路径。 mkdir命令的常用参数选项如下。 -p&#xff1a;在创…

通过dem2terrain生成MapboxGL地形服务

概述 MapboxGL在2的版本之后通过地形服务开始支持三维的展示了&#xff0c;之前也有文章“mapboxGL2中Terrain的离线化应用”对该服务进行过说明与分析。前些天在翻公众号的时候翻到了dem2terrain可以生成地形服务&#xff0c;同时做了一些优化&#xff0c;今天就给大家分享一…

畅享免费服务:PDF 转图片在线转换软件的魅力

为了方便在社交媒体上分享文档内容&#xff0c;还为了更好地适应特定的编辑需求&#xff0c;将 PDF 文件转换为图片格式都具有重要的意义。而如今&#xff0c;幸运的是&#xff0c;有许多pdf转图片在线转换免费工具为我们提供了便捷、高效的 PDF 转图片服务。接下来&#xff0c…

MongoDB 数据库服务搭建(单机)

下载地址 下载测试数据 作者&#xff1a;程序那点事儿 日期&#xff1a;2023/02/15 02:16 进入下载页&#xff0c;选择版本后&#xff0c;右键Download复制连接地址 下载安装包 ​ wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-5.0.14.tgz​ …

Redis: Sentinel哨兵监控架构及环境搭建

概述 在主从模式下&#xff0c;我们通过从节点只读模式提高了系统的并发能力并发不断增加&#xff0c;只需要扩展从节点即可&#xff0c;只要主从服务器之间&#xff0c;网络连接正常主服务器就会将写入自己的数据同步更新给从服务器&#xff0c;从而保证主从服务器的数据相同…