java linux 系统队列,Java队列存储结构及实现

一、队列(Queue)

队列是一种特殊的线性表,它只允许在表的前段(front)进行删除操作,只允许在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。

对于一个队列来说,每个元素总是从队列的rear端进入队列,然后等待该元素之前的所有元素出队之后,当前元素才能出对,遵循先进先出(FIFO)原则。

如果队列中不包含任何元素,该队列就被称为空队列。

Java提供了一个Queue接口,并为该接口提供了众多的实现类:ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、PriorityQueue、ConcurrentLinkedQueue和SynchronousQueue。

其中常用的是:ArrayBlockingQueue、LinkedBlockingQueue和CurrentLinkedQueue,它们都是线程安全的队列。LinkedBlockingQueue队列的吞吐量通常比ArrayBlockingQueue队列高,但在大多数并发应用程序中,LinkedBlockingQueue的性能要低。

除了LinkedBlockingQueue队列之外,JDK还提供了另外一种链队列ConcurrentLinkedQueue,它基于一种先进的、无等待(wait-free)队列算法实现。

二、顺序队列存储结构的实现

package com.ietree.basic.datastructure.queue;

import java.util.Arrays;

/**

* Created by ietree

* 2017/4/29

*/

public class SequenceQueue {

private int DEFAULT_SIZE = 10;

// 保存数组的长度

private int capacity;

// 定义一个数组用于保存顺序队列的元素

private Object[] elementData;

// 保存顺序队列中元素的当前个数

private int front = 0;

private int rear = 0;

// 以默认数组长度创建空顺序队列

public SequenceQueue() {

capacity = DEFAULT_SIZE;

elementData = new Object[capacity];

}

// 以一个初始化元素来创建顺序队列

public SequenceQueue(T element) {

this();

elementData[0] = element;

rear++;

}

/**

* 以指定长度的数组来创建顺序线性表

*

* @param element  指定顺序队列中第一个元素

* @param initSize 指定顺序队列底层数组的长度

*/

public SequenceQueue(T element, int initSize) {

this.capacity = initSize;

elementData = new Object[capacity];

elementData[0] = element;

rear++;

}

/**

* 获取顺序队列的大小

*

* @return 顺序队列的大小值

*/

public int length() {

return rear - front;

}

/**

* 插入队列

*

* @param element 入队列的元素

*/

public void add(T element) {

if (rear > capacity - 1) {

throw new IndexOutOfBoundsException("队列已满异常");

}

elementData[rear++] = element;

}

/**

* 移除队列

*

* @return 出队列的元素

*/

public T remove() {

if (empty()) {

throw new IndexOutOfBoundsException("空队列异常");

}

// 保留队列的rear端的元素的值

T oldValue = (T) elementData[front];

// 释放队列顶元素

elementData[front++] = null;

return oldValue;

}

// 返回队列顶元素,但不删除队列顶元素

public T element() {

if (empty()) {

throw new IndexOutOfBoundsException("空队列异常");

}

return (T) elementData[front];

}

// 判断顺序队列是否为空

public boolean empty() {

return rear == front;

}

// 清空顺序队列

public void clear() {

// 将底层数组所有元素赋值为null

Arrays.fill(elementData, null);

front = 0;

rear = 0;

}

public String toString() {

if (empty()) {

return "[]";

} else {

StringBuilder sb = new StringBuilder("[");

for (int i = front; i < rear; i++) {

sb.append(elementData[i].toString() + ", ");

}

int len = sb.length();

return sb.delete(len - 2, len).append("]").toString();

}

}

}

测试类:

package com.ietree.basic.datastructure.queue;

/**

* Created by ietree

* 2017/4/30

*/

public class SequenceQueueTest {

public static void main(String[] args) {

SequenceQueue queue = new SequenceQueue();

// 依次将4个元素加入到队列中

queue.add("aaaa");

queue.add("bbbb");

queue.add("cccc");

queue.add("dddd");

System.out.println(queue);

System.out.println("访问队列的front端元素:" + queue.element());

System.out.println("第一次弹出队列的front端元素:" + queue.remove());

System.out.println("第二次弹出队列的front端元素:" + queue.remove());

System.out.println("两次remove之后的队列:" + queue);

}

}

程序输出:

[dddd, cccc, bbbb, aaaa]

访问栈顶元素:dddd

第一次弹出栈顶元素:dddd

第二次弹出栈顶元素:cccc

两次pop之后的栈:[bbbb, aaaa]

三、队列的链式存储结构实现

package com.ietree.basic.datastructure.queue;

/**

* Created by ietree

* 2017/4/30

*/

public class LinkQueue {

// 定义一个内部类Node,Node实例代表链队列的节点

private class Node {

// 保存节点的数据

private T data;

// 指向下个节点的引用

private Node next;

// 无参构造器

public Node() {

}

// 初始化全部属性的构造器

public Node(T data, Node next) {

this.data = data;

this.next = next;

}

}

// 保存该链队列的头节点

private Node front;

// 保存该链队列的尾节点

private Node rear;

// 保存该链队列中已包含的节点数

private int size;

// 创建空链队列

public LinkQueue() {

// 空链队列,front和rear的值都为null

front = null;

rear = null;

}

// 以指定数据元素来创建链队列,该链队列只有一个元素

public LinkQueue(T element) {

front = new Node(element, null);

// 只有一个节点,front、rear都是指向该节点

rear = front;

size++;

}

// 返回链队列的长度

public int length() {

return size;

}

// 将新元素加入队列

public void add(T element) {

// 如果该链队列还是空链队列

if (front == null) {

front = new Node(element, null);

// 只有一个节点,front、rear都是指向该节点

rear = front;

} else {

// 创建新节点

Node newNode = new Node(element, null);

// 让尾节点的next指向新增的节点

rear.next = newNode;

rear = newNode;

}

size++;

}

// 删除队列front端的元素

public T remove() {

Node oldfront = front;

// 让front引用指向原队列顶元素的下一个元素

front = front.next;

// 释放原队列顶元素的next引用

oldfront.next = null;

size--;

return oldfront.data;

}

// 访问队列顶元素,但不删除队列顶元素

public T element() {

return rear.data;

}

// 判断链队列是否为空队列

public boolean empty() {

return size == 0;

}

// 请空链队列

public void clear() {

// 将front、rear两个节点赋为null

front = null;

rear = null;

size = 0;

}

public String toString() {

// 链队列为空队列时

if (empty()) {

return "[]";

} else {

StringBuilder sb = new StringBuilder("[");

for (Node current = front; current != null; current = current.next) {

sb.append(current.data.toString() + ", ");

}

int len = sb.length();

return sb.delete(len - 2, len).append("]").toString();

}

}

}

测试类:

package com.ietree.basic.datastructure.queue;

/**

* Created by ietree

* 2017/4/30

*/

public class LinkQueueTest {

public static void main(String[] args) {

LinkQueue queue = new LinkQueue("aaaa");

// 依次将4个元素加入到队列中

queue.add("bbbb");

queue.add("cccc");

queue.add("dddd");

System.out.println(queue);

// 删除一个元素后

queue.remove();

System.out.println("删除一个元素后的队列:" + queue);

// 再添加一个元素

queue.add("eeee");

System.out.println("再次添加元素后的队列:" + queue);

}

}

程序输出:

[aaaa, bbbb, cccc, dddd]

删除一个元素后的队列:[bbbb, cccc, dddd]

再次添加元素后的队列:[bbbb, cccc, dddd, eeee]

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值