https://en.wikipedia.org/wiki/Circular_buffer

某大外企面试问到到一个,当时有点紧张,然后用链表实现,最后写的也有些问题,要求的单元测试也没有完成。

两种实现,使用数组或者链表,相对来说不需要随机访问,使用链表会更好,实现上链表也更容易些。

接口定义,实际使用应该定义泛型接口

package com.ljw.javatest;

// Ringbuffer is a circle, and has a head and tail.
// When add item, add item at tail, if item's quantity exceed max,
// then delete the head item.
public interface RingBuffer{ public void addItem(int value);
//return the oldest item
public Integer getItem();
//delege the oldest item
public void deleteItem();
//return item from head to tail
public Integer[] getAll();
}

链表实现,定义了一个内部类存储节点

package com.ljw.javatest;

public class RingBufferWithLinked implements RingBuffer{

    class Node{
Integer value;
Node next;
Node(Integer value){
this.value=value;
}
} private int max;
private int count;
private Node head;
private Node tail; public RingBufferWithLinked(int max) throws Exception {
if(max<=0){
throw new Exception("invalid max");
}
this.max=max;
this.count=0;
} @Override
public void addItem(int value) {
if(head==null){
head=new Node(value);
tail=head;
count++;
return;
} Node temp = new Node(value); tail.next = temp;
tail = temp;
if (count < max) {
count++;
return;
}
head=head.next; } @Override
public Integer getItem() {
if(head!=null){
return head.value;
}
return null;
} @Override
public void deleteItem() {
if(head==null){
return;
}
head=head.next;
count--;
if(count==0){
head=tail=null;
}
} @Override
public Integer[] getAll() {
if(head==null){
return null;
}
Integer[] result=new Integer[count];
int i=0;
Node temp=head;
while(temp!=null){
result[i++]=temp.value;
temp=temp.next;
}
return result;
} }

数组实现,如果说不好,可能就是需要分配连续空间,以及最大不能超过数组最大长度

package com.ljw.javatest;

import java.util.List;

public class RingBufferWithArray implements RingBuffer {

    public static void main(String[] args) {

    }

    Integer[] buffer;
int head;
int tail;
int max;
int count; public RingBufferWithArray(int max) throws Exception {
if (max <= 0) {
throw new Exception("invalid max");
}
buffer = new Integer[max];
this.max = max;
count = 0;
head = -1;
tail = -1;
} @Override
public void addItem(int value) {
if (count + 1 > max) {
buffer[head] = value;
tail = head;
if (head == max - 1) {
head = 0;
} else {
head++;
}
} else {
count++;
if (count == 1) {
head=tail=0;
buffer[head]=value;
}
else {
if (tail == max - 1) {
tail = 0;
buffer[tail] = value;
} else {
buffer[++tail] = value;
}
}
}
} @Override
public Integer getItem() {
if (head == -1) {
return null;
} else {
return buffer[head];
}
} @Override
public void deleteItem() {
if (count == 0) {
return;
}
buffer[head] = null;
count--;
if (count == 0) {
head = tail = -1;
}
if (head++ == max) {
head = 0;
}
} @Override
public Integer[] getAll() {
if (head == -1) {
return null;
} Integer[] result = new Integer[count];
for (int i = 0, temp = head; i < count; i++, temp++) {
if (temp == max) {
temp = 0;
}
result[i] = buffer[temp];
}
return result; } }

测试,主要的边界情况是max=1,以及增加元素超过时如何处理。

package com.ljw.javatest;

public class App {
public static void main(String[] args) throws Exception {
int max=3;//max=1;
RingBuffer rb=new RingBufferWithLinked(max);
rb.addItem(1);
print(rb.getItem()==1);
rb.deleteItem();
print(rb.getItem()==null); int add=2;
for(int i=0;i<max+add;i++){
rb.addItem(i);
} Integer[] result=rb.getAll();
for(int i=0;i<max;i++){
print(result[i]==i+add);
} } public static void print(Object value){
System.out.println(value);
}
}

算法 RingBuffer的更多相关文章

  1. 算法:基于 RingBuffer 的 Queue 实现《续》

    背景 上篇实现了一个简单的队列,内部使用了 _count 计数,本文采用另外一种模式,不用 _count 计数. RingBuffer 不用 _count 计数的话,为了区分队列的满和空,需要在数组中 ...

  2. 算法:基于 RingBuffer 的 Queue 实现

    背景 如果基于数组实现队列,常见的选择是采用 RingBuffer,否则就需要移动数组元素. RingBuffer 很容易看出 RingBuffer 的思想,这里就不赘述了. 您可以思考一个问题:图中 ...

  3. 算法:基于 RingBuffer 的 Deque 实现

    背景 前两篇文章介绍了 Queue 的实现,很多类库都引入了 Deque,Deque 可以两头添加和删除,然后在 Deque 之上构建 Queue 和 Stack. Deque 代码 using Sy ...

  4. 算法(第四版)C# 习题题解——2.2

    写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 查找更为方便的版本见:http ...

  5. 算法(第四版)C# 习题题解——1.3

    写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 这一节内容可能会用到的库文件有 ...

  6. Disruptor底层实现讲解与RingBuffer数据结构讲解

    Disruptor术语 RingBuffer:被看作Disruptor最主要的组件,然而从2.0开始RingBuffer仅仅负责存储和更新在Disruptor中流通的数据.对一些特殊的使用场景能够被用 ...

  7. 从NLP任务中文本向量的降维问题,引出LSH(Locality Sensitive Hash 局部敏感哈希)算法及其思想的讨论

    1. 引言 - 近似近邻搜索被提出所在的时代背景和挑战 0x1:从NN(Neighbor Search)说起 ANN的前身技术是NN(Neighbor Search),简单地说,最近邻检索就是根据数据 ...

  8. 一篇文章彻底搞懂snowflake算法及百度美团的最佳实践

    写在前面的话 一提到分布式ID自动生成方案,大家肯定都非常熟悉,并且立即能说出自家拿手的几种方案,确实,ID作为系统数据的重要标识,重要性不言而喻,而各种方案也是历经多代优化,请允许我用这个视角对分布 ...

  9. 物联网安全himqtt防火墙数据结构之ringbuffer环形缓冲区

    物联网安全himqtt防火墙数据结构之ringbuffer环形缓冲区 随着5G的普及,物联网安全显得特别重要,himqtt是首款完整源码的高性能MQTT物联网防火墙 - MQTT Applicatio ...

  10. 彻底搞懂snowflake算法及百度美团的最佳实践

    写在前面的话 一提到分布式ID自动生成方案,大家肯定都非常熟悉,并且立即能说出自家拿手的几种方案,确实,ID作为系统数据的重要标识,重要性不言而喻,而各种方案也是历经多代优化,请允许我用这个视角对分布 ...

随机推荐

  1. LiveGBS GB28181国标流媒体对几万路摄像头接入时如何配置切换成Mysql_Mariadb数据库

    GB28181流媒体服务 LiveGBS具体介绍这边不多说,参考https://www.liveqing.com/docs/products/LiveGBS.html 配置接入mysql数据库 Liv ...

  2. 洛谷 P7913 [CSP-S 2021] 廊桥分配 题解

    题目描述请移步 https://www.luogu.com.cn/problem/P7913 题目简述 有一座机场,分为国际区和国外区,机场共有n个廊桥,国内国际分别有m1,m2架飞机,给定每架飞机抵 ...

  3. CF351C Jeff and Brackets

    CF351C Jeff and Brackets 广义矩阵加速 DP 题意 构造一个长度为 \(n×m\) 的合法括号序列. 第 \(i\) 个位置上的左括号代价为 \(a_{i~\text{mod} ...

  4. linux系统编程01-文件系统

    目录 介绍 一.目录和文件 1. 获取文件的属性 : stat 2.文件属性 3.umask 4.文件权限管理 5.粘住位 6.文件系统:FAT.UFS 7.硬链接,符号链接 9. 文件目录解析 : ...

  5. dubbo分布式系统

    RPC 远程过程调用 @EnableDubbo 服务注册 netty, redis rabbitmq

  6. Grafana 和 Openssh 高危漏洞修复

    本次漏洞扫描,扫描到的高危漏洞涉及Grafana和Openssh,其中Grafana发现漏洞有(CVE-2023-3128.CVE-2022-23498.CVE-2023-4822.CVE-2024- ...

  7. .NET 何以成为制造业数字化转型的基石:效率、生态与跨平台的制胜之道

    在制造业,特别是半导体设备通信领域,.NET因其开发效率.跨平台能力和成熟的生态系统,已成为主流技术之一.这篇文章做个具体分析制造业为什么钟爱.NET 技术. 一..NET在制造业的应用 半导体设备通 ...

  8. WxPython跨平台开发框架之主从表展示和录入的界面处理--产品报价单和明细记录的处理

    我们在前面随笔<Vue3+ElementPlus的BS端主从表的快速开发>了解了Vue3+ElementPlus的BS端主从表的实现,了解了大概的设计和界面设计方式,我们现在切换一下,看看 ...

  9. GapBuffer高效标记管理算法

    目录 引言 GapBuffer 基本思想 基本操作 基于下标映射的标记记录法 下标映射 搜索 维护 对比 总结 引言 最近笔者正在优化 Android 开源代码编辑器项目 TextWarrior 的一 ...

  10. m基于GA遗传优化的多因素加权竞价博弈频谱分配算法matlab仿真

    1.算法描述 假设有M个用户均为MIMO Full Duplex,N个频率,1<N<M,设计算法实现M个用户与N个频率的匹配. 由于在一个MIMO系统中,用户数量M大于可用的频谱个数N,因 ...