Java實現環形佇列
阿新 • • 發佈:2019-01-08
這裡我定義的環形佇列為:列表中最後一個元素是指向列表中的第一個元素,而且裡面提供一個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);
}
}