【左程云算法笔记016】双端队列-双链表和固定数组实现 - 教程

news/2025/9/21 21:08:07/文章来源:https://www.cnblogs.com/lxjshuju/p/19104167

目录

1)双端队列的介绍

2)双端队列用双链表的实现代码演示

3)双端队列用固定数组的实现

代码演示


视频

【算法讲解016【入门】双端队列-双链表和固定数组实现】

Leecode

leecode641 设计循环双端队列


1)双端队列的介绍

可以从头部进,可以从头部出;也可以从尾部进,可以从尾部出。这种结构叫双端队列

双向链表为了跳转容易,在数外边设置一个节点包着,前指针,后指针。

比如我之前有个a,头指空,尾指空。

我现在又加了个b,那么b的头指针指向a,尾指针指向空,尾巴来到b上

我再加个c,一样的。我又想在头部加个d,一样思路所以头部加数 尾部加数就会了

头部弹出 尾部弹出怎么办?

头部弹出

头移到a,a的前指针指向null,c或c++的同学把d释放掉,java会自己释放不用管。

同样方法把a弹出。

想从尾部弹出呢?

尾巴向前跳一个,让b的next指针指向空。c或c++的同学把d释放掉,java会自己释放不用管。

2)双端队列用双链表的实现代码演示

package C16;
import java.util.Deque;
import java.util.LinkedList;
public class Video_016_Deque {
class MyCircularDeque1{
//Deque是接口 是泛型,相当于Deque 的意思就是:“这是一个双端队列,并且我给它贴上了**‘只能存放整数 (Integer)’**的标签。”
public Deque deque = new LinkedList<>();
//“我要声明 (declare) 一个变量,它的名字叫 deque。这个变量是 public(公开)的,并且它的类型是一个贴着 Integer(整数)标签的 Deque(双端队列功能清单)。”
public int size;
public int limit;
/**
* 初始化一个容量为k的双端队列
* @param k 队列的容量
*/
public MyCircularDeque1(int k){
//“现在,我要创建一个真正能干活的工人(new LinkedList<>()),这个工人完全遵守了 Deque 的规范,然后让我的 deque 变量去管理(指向)这个工人。”
deque = new LinkedList<>();
//初始时,队列中没有元素
size = 0;
//设置容量上限
limit = k;
}
/**
* 将一个元素添加到队首,如果操作成功,返回true
*/
public boolean insertFront(int value) {
//在插入前检查队列是否已满
if(isFull()){
return false;//满了,添加失败
}
//调用LinkList自带的方法offerFirst(),它会高效地将元素添加到链表头部
deque.offerFirst(value);
//元素数量加1
size++;
//插入成功
return true;
}
/**
* 将一个元素添加到队尾,如果操作成功返回true
*/
public boolean insertLast(int value){
//同样先检查队列是否已经满了
if(isFull()){
return false;
}
//调用自带的方法offerLast(),它会高效地将元素添加到链表尾部
deque.offerLast(value);
size++;
return true;
}
/**
* 从队首删除一个元素,如果操作成功返回true
*/
public boolean deleteFront(){
//跟之前一样的操作
if(isEmpty()){
return false;
}
deque.pollFirst();
size--;
return true;
}
public boolean deleteLast(){
if(isEmpty()){
return false;
}
deque.pollLast();
size--;
return true;
}
/**
* 从队首获取元素,如果队列为空返回-1
*/
public  int getFront(){
if (isEmpty()) {
return -1;
}
// 调用 LinkedList 自带的 peekFirst(),它只查看头部的元素,不移除。
return deque.peekFirst();
}/**
* 获取队尾元素。如果队列为空,返回 -1。
* @return 队尾的元素,或 -1。
*/
public int getRear() {
if (isEmpty()) {
return -1;
}
// 调用 LinkedList 自带的 peekLast(),它只查看尾部的元素,不移除。
return deque.peekLast();
}
/**
* 检查双端队列是否为空。
* @return 为空返回 true,否则返回 false。
*/
public boolean isEmpty() {
// 我们自己维护了 size 变量,用它来判断最简单。
return size == 0;
}
/**
* 检查双端队列是否已满。
* @return 已满返回 true,否则返回 false。
*/
public boolean isFull() {
// 当 size 达到容量上限时,队列就满了。
return size == limit;
}
}
}

3)双端队列用固定数组的实现

用固定数组(动态也可以)

size,l,r

有没有数字或者满没满,size管。如果size等于0,那么l和r等于啥都没意义。

当加入数字a时,把a放在第零位,l到r位置上放a。即第零位到第零位放a。size变为1。

再加入b,r变为第一位。size再加1。

再加c

再加d。

头部再加个e。

怎么做?

l已经在第零位了,怎么办?

加到最后的位置上。

一共不是k位吗?这道题k是10,所以l来到第k-1位置上,即第9位。所以说总结头部添加的办法:当l==0时,放在第k-1位,l=k-1;

当l≠0时,放在第l-1位,l--。

比如再在头部加个f所以现在从头部到尾部的就是890123这样的顺序。

如果再在头部加个g弹出呢?

从头部弹出,也就是l往右窜。即总结为:头部加数那么l往左窜,头部弹数则l往右窜。这就是l的逻辑。

模拟一下全过程

原来是这样

弹出g

弹出f弹出e..

弹出a

弹出b

加入k加入s,加入p,加入l,加入n...

在尾部加入M

所以现在的整个队列就是cdkspcznm

从尾巴弹出总结一下:

从头部加入,l向左走,如果l==0,把数放在k-1的位置,然后赋值l=k-1;

如果l≠0,那么把数放在l-1的位置,然后赋值l--;

从头部出,首先给用户l位置的数[l],如果l==k-1,那么赋值l=0;

如果l≠k-1,那么赋值l++;

从尾部入,如果l==k-1,把数放在0的位置,然后赋值r=0;

如果r≠k-1,那么把数放在r+1的位置,然后赋值r++;

从尾出,首先给用户r位置的数[r],然后要往左走,所以如果r==0,那么r赋值为k-1,即第k-1位;

如果r≠0呢?从尾出那么就是r--就行了。

这就是所有的逻辑 环形双端队列

代码演示

public class MyCircularDeque2 {
//底层的数据容器,一个固定大小的数组
public  int[] deque;
//l:left/front指针,指向队头元素所在的索引
//r:right/rear指针,指向队尾元素所在的索引
//size:当前队列中的元素数量
//limit:队列的容量上限(数组的大小)
public int l,r,size,limit;
/**
* 构造方法:初始化一个容量为k的双端队列
*/
public MyCircularDeque2(int k){
//创建一个能容纳k个整数的数组
deque = new int[k];
//初始时,所有指针和计数器都为0(或者一个无效状态)
l = r = size = 0;
//设置容量上限
limit = k;
}
/**
* 将一个元素添加到队首
*/
public boolean insertFront(int value){
//先检查是否已经满
if(isEmpty()){
//队头和队尾指针都指向0号位置
l = r = 0;
//在0号位置放入新元素
deque[0] = value;
}else{
//如果不为空,我们需要l往左移动,但如果它本来就在最左边,所以我们将它移动到limit-1位置上
l = l ==0?(limit - 1):(l - 1);
//在计算出的新位置l放入元素
deque[1] = value;
}
//元素数量加1
size++;
return true;
}
/**
* 将一个元素添加到队尾。
*/
public boolean insertLast(int value) {
if (isFull()) {
return false;
}
if (isEmpty()) {
// 和 insertFront 一样,第一个元素 l 和 r 都指向 0
l = r = 0;
deque[0] = value;
} else {
// 移动 r 指针,为新元素在“后面”腾出位置
// 这是另一个“循环”的关键!
// r == limit - 1 ? 0 : (r + 1)
// 意思是:
// 如果 r 指针已经在末尾了 (limit - 1),那么它的“后一个”位置就是环绕到开头的 0。
// 否则,它的后一个位置就是 r + 1。
r = r == limit - 1 ? 0 : (r + 1);
// 在计算出的新位置 r 放入元素
deque[r] = value;
}
size++;
return true;
}
/**
* 从队首删除一个元素。
*/
public boolean deleteFront() {
if (isEmpty()) {
return false;
}
// 删除队首元素,我们只需要把 l 指针向“后”移动一位即可
// 同样是循环移动
// l == limit - 1 ? 0 : (l + 1)
// 意思是:如果 l 在末尾,下一个位置是 0;否则是 l + 1
l = l == limit - 1 ? 0 : (l + 1);
// 元素数量减 1
size--;
return true;
}
/**
* 从队尾删除一个元素。
*/
public boolean deleteLast() {
if (isEmpty()) {
return false;
}
// 删除队尾元素,我们只需要把 r 指针向“前”移动一位
// 循环移动
// r == 0 ? (limit - 1) : (r - 1)
// 意思是:如果 r 在开头,前一个位置是 limit - 1;否则是 r - 1
r = r == 0 ? (limit - 1) : (r - 1);
size--;
return true;
}
/**
* 从队首获取元素。
*/
public int getFront() {
if (isEmpty()) {
return -1;
}
// 队首元素就是 l 指针指向的元素
return deque[l];
}
/**
* 获取队尾元素。
*/
public int getRear() {
if (isEmpty()) {
return -1;
}
// 队尾元素就是 r 指针指向的元素
return deque[r];
}
public boolean isEmpty() {
return size == 0;
}
public boolean isFull() {
return size == limit;
}
}

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

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

相关文章

LeetCode 几道 Promises 和 Time 的题目 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

[硬件电路-232]:FET(场效应管)的核心机制是通过栅极电压调控半导体“沟道“中的载流子浓度与分布,进而控制源极与漏极之间的电流大小 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

java相关问题:面向对象入门2与类的识别

1. 关于 static 修饰符 应该用 static 修饰的方法: *不依赖于特定对象的实例状态:执行的操作不访问或修改对象的实例变量。 *工具类方法:常用于定义工具类中的方法,这些方法提供通用功能,无需创建类实例。 *工厂方…

EXCEL自动调整列宽的快捷键

在 Excel 中,自动调整列宽的快捷键是:Windows 系统:先选中要调整的列(可选中单列或多列),然后按下 Alt + H + O + I(依次按下这些键)。 Mac 系统:先选中要调整的列,然后按下 Command + Option + H + O + I。…

【C++实战⑬】解锁C++文件操作:从基础到实战的进阶之路 - 实践

【C++实战⑬】解锁C++文件操作:从基础到实战的进阶之路 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Co…

破解塔吊顶升高危难题!让事故率降 50%、审批快 70%

在建筑施工领域,塔吊顶升作业作为关键且高危的环节,长期以来饱受诸多痛点的困扰,严重影响施工安全与进度。传统模式下,人工对塔吊顶升作业的审查多依赖现场巡检,然而人力有限,在忙碌的施工现场,难以做到时刻紧盯…

logicFlow________文档2

# LogicFlow 官方指南 - 自定义连线与事件处理## 📖 概述LogicFlow 是滴滴开源的一款流程图编辑框架,具有强大的扩展性和自定义能力。本文档基于LogicFlow官网最新版本,详细介绍如何实现自定义连线、自定义事件处理…

CF2086D Even String

题目链接:Problem - D - Codeforces 本身是一道数学题,我们可以把字符串中的奇数项和偶数项分开,形成两条序列 A 和 B。易知一种字母一定在同一条序列上。 假如说在 A 序列上分配了 \(a,b,c\) 三种字母,\(sum = c_…

logicflow___文档3

# LogicFlow 流程图编辑器开发文档## 📖 概述这是一个基于 LogicFlow 的流程图编辑器完整开发指南,包含详细的代码示例和实现方案。该编辑器支持节点创建、连接线绘制、关系管理等功能。## 🚀 快速开始### 1. 安装…

langraph-up-react

langraph-up-react https://github.com/fanqingsong/langraph-up-reactLangGraph ReAct Agent TemplateThis template showcases a ReAct agent implemented using LangGraph, works seamlessly with LangGraph Studio…

2025年运营商API安全建设最佳实践:某头部省级电信案例解析与方案推荐

2025年运营商API安全建设最佳实践:某头部省级电信案例解析与方案推荐运营商API安全需应对资产可视性缺失、动态风险防护不足、合规压力三大挑战。全知科技(Data-Sec)知影-API风险监测系统通过“规则引擎+AI引擎”双轮…

软件工程第二次作业-第一次个人编程作业

个人编程作业项目 内容这个作业属于哪个课程 [软件工程](首页 - 计科23级12班 - 广东工业大学 - 班级博客 - 博客园)这个作业要求在哪里 [作业要求](个人项目 - 作业 - 计科23级12班 - 班级博客 - 博客园)这个作业的目…

面向对象入门2与类的识别

一、什么样的方法应该用static修饰?不用static修饰的方法往往具有什么特性?Student的getName应该用static修饰吗?static 修饰方法的适用场景应该用 static 修饰的方法:方法与对象的状态无关,只依赖传入的参数完成…

202508_天山固网_to

流量分析,dvorak键盘解码, 大小写转二进制, BIN2QRCODETags:流量分析,dvorak键盘解码,大小写转二进制,BIN2QRCODE 0x00. 题目 【天山固网——2025网络安全技能竞赛】 children of stream 附件路径:https://pan.baid…

Java学生信息管理系统代码分析

Java学生信息管理系统代码分析学生信息管理系统代码分析 功能讲解 数据处理 该程序主要处理学生信息数据,包括学生的姓名、年龄、性别、学号、专业和 GPA 等信息。这些数据通过Student类的对象进行封装,并存储在Stud…

ArcGIS Pro中 Nodata和nan 黑边的处理 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

怎么屏蔽 ahref.com 上你不想看到的网站链接(垃圾外链)

怎么屏蔽 ahref.com 上你不想看到的网站链接(垃圾外链)在 ahref 网站查看自己网站或别人网站的外链时,查询的结果里面总会充斥着各种垃圾网站的链接,你一点击过去就会弹出一个聊天窗口或者是什么广告。 虽然时间久…

浅谈字典树

本篇文章同步发表在洛谷博客。字典树 什么是字典树? 字典树,顾名思义它是一棵类似于字典的树,用树的形态存储字符串集合。具体地,它有一个自定义的无意义的根节点(通常编号为 \(0\) 或 \(1\)),所有存储进去的字…

go-mapus为局域网地图协作而生

很多年前就用mapus了,它是用实时数据库实现协作功能。可是实时数据库是国外的,不好用,速度慢,经常封掉。 这次直接用sqlite,简单快捷,加上websocket即可,没有原来想象的那么玄乎,代码也就几千行。 我把几十G的…

【工具变量】“国家级大数据综合试验区”试点城市DID(2000-2024年) - 教程

【工具变量】“国家级大数据综合试验区”试点城市DID(2000-2024年) - 教程2025-09-21 20:28 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x…