数据结构——环形数组

embedded/2025/3/19 0:31:30/

环形数组

start 指向第一个有效元素的索引,end 指向最后一个有效元素的下一个位置索引。

注意: start是闭区间,先左移后赋值,先赋值(null)后右移;end是开区间,先赋值再右移,先左移再赋值(null)。

左移减一加size再取模,右移加一再取模。

JS代码实现:

class CycleArray {
constructor(size = 1) {this.size = size;this.arr = new Array(size);// start 指向第一个有效元素的索引,闭区间this.start = 0;// 切记 end 是一个开区间,// 即 end 指向最后一个有效元素的下一个位置索引this.end = 0;this.count = 0;
}resize(newSize) {// 创建新的数组var newArr = new Array(newSize);// 将旧数组的元素复制到新数组中for (var i = 0; i < this.count; i++) {newArr[i] = this.arr[(this.start + i) % this.size];}this.arr = newArr;// 重置 start 和 end 指针this.start = 0;this.end = this.count;this.size = newSize;
}// 在数组头部添加元素,时间复杂度 O(1)
addFirst(val) {// 当数组满时,扩容为原来的两倍if (this.isFull()) {this.resize(this.size * 2);}// 因为 start 是闭区间,所以先左移,再赋值this.start = (this.start - 1 + this.size) % this.size;this.arr[this.start] = val;this.count++;
}// 删除数组头部元素,时间复杂度 O(1)
removeFirst() {if (this.isEmpty()) {throw new Error("Array is empty");}// 因为 start 是闭区间,所以先赋值,再右移this.arr[this.start] = null;this.start = (this.start + 1) % this.size;this.count--;// 如果数组元素数量减少到原大小的四分之一,则减小数组大小为一半if (this.count > 0 && this.count == this.size / 4) {this.resize(this.size / 2);}
}// 在数组尾部添加元素,时间复杂度 O(1)
addLast(val) {if (this.isFull()) {this.resize(this.size * 2);}// 因为 end 是开区间,所以是先赋值,再右移this.arr[this.end] = val;this.end = (this.end + 1) % this.size;this.count++;
}// 删除数组尾部元素,时间复杂度 O(1)
removeLast() {if (this.isEmpty()) {throw new Error("Array is empty");}// 因为 end 是开区间,所以先左移,再赋值this.end = (this.end - 1 + this.size) % this.size;this.arr[this.end] = null;this.count--;// 缩容if (this.count > 0 && this.count == this.size / 4) {this.resize(this.size / 2);}
}// 获取数组头部元素,时间复杂度 O(1)
getFirst() {if (this.isEmpty()) {throw new Error("Array is empty");}return this.arr[this.start];
}// 获取数组尾部元素,时间复杂度 O(1)
getLast() {if (this.isEmpty()) {throw new Error("Array is empty");}// end 是开区间,指向的是下一个元素的位置,所以要减 1return this.arr[(this.end - 1 + this.size) % this.size];
}isFull() {return this.count === this.size;
}size() {return this.count;
}isEmpty() {return this.count === 0;
}
}

http://www.ppmy.cn/embedded/173715.html

相关文章

瑞幸需要宇树科技

吃不到“星巴克红利”&#xff0c;瑞幸活成“Manner”。 作者|古廿 编辑|杨舟 “是不是又要开始3月革命了。”有瑞幸员工透露&#xff0c;今年开始瑞幸加强了系统排班的执行力度。新的排班体系下&#xff0c;要求各时段门店实际值班人员和排班系统一致。如果需要调整&#xf…

WireShark自动抓包

背景 异常流量检测是当前保护网络空间安全的重要检测方法。 对流量的研究&#xff0c;首先需要在系统中进行抓包&#xff0c;并对包进行分析。 这里对WireShark自动抓包进行简要介绍。 操作步骤 1、选择“捕获”>“选项”。 2、在Input下&#xff0c;选择要抓包的网络接…

Redisson 实现分布式锁源码浅析

大家好&#xff0c;我是此林。 今天来分享Redisson分布式锁源码。还是一样&#xff0c;我们用 问题驱动 的方式展开讲述。 1. redis 中如何使用 lua 脚本&#xff1f; Redis内置了lua解释器&#xff0c;lua脚本有两个好处&#xff1a; 1. 减少多次Redis命令的网络传输开销。…

PosterRender 实现微信下程序 分享商品生成海报

PosterRender 是什么 PosterRender 是一种专注于生成高质量海报图像的技术或工具&#xff0c;常用于生成静态图片&#xff0c;特别是适合用于营销、宣传和展示的图形设计。它通常用于在服务端或客户端渲染复杂的图像&#xff0c;包括文字、图形、图标、背景等&#xff0c;生成…

LLMs之CoTM:《Detecting misbehavior in frontier reasoning models》翻译与解读

LLMs之CoTM&#xff1a;《Detecting misbehavior in frontier reasoning models》翻译与解读 导读&#xff1a;这篇OpenAI的论文介绍了一种名为“思维链监控”&#xff08;Chain-of-Thought Monitoring&#xff0c;CoT Monitoring&#xff09;的技术&#xff0c;旨在提高大型语…

Doris vs Elasticsearch:全维度对比与实际成本案例解析

在大数据实时分析与日志检索场景中&#xff0c;企业常用的技术方案主要集中在 Elasticsearch 与 Apache Doris 两大产品上。Elasticsearch 以强大的全文检索和灵活的聚合功能著称&#xff0c;而 Doris 则凭借分布式 MPP 架构、列式存储以及日益完善的倒排索引能力&#xff0c;在…

【5*】坐标规则类动态规划学习笔记

前言 此类知识点大纲中并未涉及&#xff0c;所以【5】是我自己的估计&#xff0c;后带星号表示估计&#xff0c;仅供参考。 坐标规则类DP 通式 d p [ i ] [ j ] max ⁡ / min ⁡ { d p [ i − k 1 ] [ j − k 2 ] } w ( i , j ) dp[i][j]\max/\min\{dp[i-k_{1}][j-k_{2}]\…

基于Python pyscard库采集ACS ACR122U NFC读卡器数据的详细操作步骤

步骤1&#xff1a;安装驱动 1. 下载驱动&#xff1a; - 访问ACS官网的驱动下载页面&#xff1a;[ACR122U驱动下载](https://www.acs.com.hk/en/drivers/6/acr122u-nfc-reader/)。 - 选择适用于Windows的驱动&#xff08;如 ACR122U Driver (Windows) V3.05.02.zip&#xff09;…