首页 > 编程语言 >Java实现环形队列

Java实现环形队列

时间:2022-11-24 17:38:15浏览次数:34  
标签:node prev return 队列 环形 next Java null public


这里我定义的环形队列为:列表中最后一个元素是指向列表中的第一个元素,而且里面提供一个next方法,可以不断获取下一个元素,在环形队列中也就是不断的转圈,实现方式如下:

队列中提供的方法:

public boolean add(E e):加入队列
public E next():加入返回当前指针元素并把指针指向下一个元素
public E prev():返回当前元素,并把指针指向上一个元素
remove(E e):删除队列中某一个元素

完整的实现代码如下:

public class CircularQueue<E> {
private int size;

//指针
private Node<E> node;

private Node<E> first;
private Node<E> last;

private final int MODE_NEXT = 0;
private final int MODE_PREV = 1;
private int lastMode = MODE_NEXT; //最后一次操作,0为next,1为prev



public CircularQueue() {

}

/**
* 加入队列
* @param e
*/
public boolean add(E e){
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, first);
last = newNode;

if (node == null) node = newNode; //指针
if (l == null) {
first = newNode;
first.prev = first;
}
else {
l.next = newNode;
first.prev = l.next;
}

size++;
return true;
}

/**
* 返回当前指针元素并把指针指向下一个元素
* @return
*/
public E next() {
if (node == null) {
return null;
}
E e = node.item;
node = node.next;

lastMode = MODE_NEXT;
return e;
}

/**
* 返回当前元素,并把指针指向上一个元素
* @return
*/
public E prev() {
if (node == null) {
return null;
}
E e = node.item;
node = node.prev;

lastMode = MODE_PREV;
return e;
}

/**
* 删除队列中某一个元素
* @param e
* @return
*/
public boolean remove(E e) {
if (e == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (e.equals(x.item)) {
unlink(x);
return true;
}
}
}

size--;
return true;
}

public E peek(){
return node.item;
}

/**
* 删除节点
*/
E unlink(Node<E> x) {
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;

if (prev == x || next == x) {
this.first = null;
this.last = null;
this.node = null;
}

next.prev = prev;
prev.next = next;

if ((element==null&&this.node.item==null) || (element.equals(this.node.item))) {
this.node = lastMode==MODE_NEXT ? this.node.next : this.node.prev;
}

x.item = null;
x = null;
size--;
return element;
}

public int size() {
return size;
}


/**
* 节点类
* @param <E>
*/
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;

Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}

}

如果在高并发的情况下需要实现线程同步的环形队列,只需要继承上面的类,为需要同步的方法加锁即可:

import java.util.concurrent.locks.ReentrantLock;

/**
* Created by giant039 on 2017/3/17.
*/
public class CircularBlockingQueue<E> extends CircularQueue<E> {
/** 对添加,删除,指针移动操作加锁 */
protected final ReentrantLock putLock = new ReentrantLock();

private QueueListener listener;

public CircularBlockingQueue() {
super();
}

public CircularBlockingQueue(QueueListener listener) {
super();
this.listener = listener;
}

public void setListener(QueueListener listener) {
this.listener = listener;
}

@Override
public boolean add(E e) {
final ReentrantLock putLock = this.putLock;
try {
putLock.lockInterruptibly();
super.add(e);

if (listener != null) listener.afterAdd(e);

return true;
} catch (InterruptedException exp) {
exp.printStackTrace();
return false;
} finally {
putLock.unlock();
}

}

@Override
public E next() {
final ReentrantLock putLock = this.putLock;
try {
putLock.lockInterruptibly();
return super.next();
} catch (InterruptedException e) {
e.printStackTrace();
return null;
} finally {
putLock.unlock();
}

}

@Override
public E prev() {
final ReentrantLock putLock = this.putLock;
try {
putLock.lockInterruptibly();
return super.prev();
} catch (InterruptedException e) {
e.printStackTrace();
return null;
} finally {
putLock.unlock();
}
}

@Override
public boolean remove(E e) {
final ReentrantLock putLock = this.putLock;
try {
putLock.lockInterruptibly();

if (listener != null) listener.afterAdd(e);

return super.remove(e);
} catch (InterruptedException exp) {
exp.printStackTrace();
return false;
} finally {
putLock.unlock();
}
}


/**
* 监听器监听插入,删除,等操作之后需要实现的功能
*/
interface QueueListener<E> {
void afterAdd(E e);
void afterRemove(E e);
}

}


标签:node,prev,return,队列,环形,next,Java,null,public
From: https://blog.51cto.com/u_15890522/5884377

相关文章

  • Java常用数据结构
    1、数组数组(Array) 是一种很常见的数据结构。它由相同类型的元素(element)组成,并且是使用一块连续的内存来存储。我们直接可以利用元素的索引(index)可以计算出该元......
  • java 数据类型
    java属于强类型语言,要求变量必须符合规定,变量必须先定义在使用。java数据类型分为两大类:基本数据类型和引用数据类型。整数拓展:二进制0b八进制0十六进制0x浮点数拓......
  • 【JAVA笔记】JAVA常用的字符串操作03
    一、Java中常用的字符串操作publicclassCommon_String_Operations{publicstaticvoidmain(String[]args){booleanp1=isEmpty("aa");S......
  • JavaScript的this指向
    1、结论:js中的this是当前方法所属的对象 'usestrict'letobj={name:'taotao',myName(){returnthis}}console.log(obj.myName())//{nam......
  • Java中File类mkdir和mkdirs的区别
    在API中,mkdir()的定义如下:创建此抽象路径名指定的目录。mkdirs()的定义如下:创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。注意,此操作失败时也可能已经成功地创......
  • [Android]java.io.FileNotFoundException: open failed: EACCES (Permission denied)
    如下错误:有很大部分原因都是忘记加权限了,我出现这个错误的原因是我往外部存储写文件,但是没有加上外部存储的权限,所以加入如下代码即可:<uses-permissionandroid:name="andro......
  • java.io.FileNotFoundException:open failed: EACCES (Permission denied)
    在android中创建一个FileOutputStream的时候,报错<spanstyle="font-size:18px;">java.io.FileNotFoundException:/storage/emulated/0/a.jpg:openfailed:EACCES(Permis......
  • java常用类中Calendar【日历】
    Calendar类Calendar:它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方......
  • java常用类之String
    packagecom.Lucky.OftenClass;importjava.util.Arrays;/*String是不可变字符串序列,所谓的String的方法都是新增一个String拓展:JDK9时,将String......
  • java工具类-发送邮件工具类
    1.普通java实现邮件发送1.1创建maven项目,配置pom.xml文件<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xm......