java队列实现方法(顺序队列,链式队列,循环队列)

双向顺序队列ArrayDeque和双向链式队列LinkedList,JDK已经包含,在此略。ArrayDeque包括顺序栈和顺序队列,LinkedList包含链式栈和链式队列。ArrayDeque和LinkedList都是线程不安全的。PriorityQueue优先队列也在JDK。

1.顺序队列的实现

package lang;
import java.io.Serializable;
import java.util.Arrays;
/**
 * @ClassName: ArrayQueue
 * @Description: 顺序队列
 * @date 2014年1月20日 下午3:46:19
 * @param <T>
 */
public class ArrayQueue<T> implements Serializable{
 /**
  * @Fields serialVersionUID : TODO
  */
 private static final long serialVersionUID = 7333344126529379197L;
 private int DEFAULT_SIZE = 10;
 private int capacity;//保存数组的长度
 private Object[] elementData;//定义一个数组用于保存顺序队列的元素
 private int front = 0;//队头
 private int rear = 0;//队尾
 //以默认数组长度创建空顺序队列
 public ArrayQueue() {
  capacity = DEFAULT_SIZE;
  elementData = new Object[capacity];
 }
 //以一个初始化元素来创建顺序队列
 public ArrayQueue(T element) {
  this();
  elementData[0] = element;
  rear++;
 }

 public ArrayQueue(int initSize) {
  elementData = new Object[initSize];
 }
 /**
  * 以指定长度的数组来创建顺序队列
  * @param element 指定顺序队列中第一个元素
  * @param initSize 指定顺序队列底层数组的长度
  */
 public ArrayQueue(T element, int initSize) {
  this.capacity = initSize;
  elementData = new Object[capacity];
  elementData[0] = element;
  rear++;
 }
 /**
  * @Title: size
  * @Description: 获取顺序队列的大小
  * @return
  */
 public int size() {
  return rear - front;
 }
 /**
  * @Title: offer
  * @Description: 入队
  * @param element
  */
 public void offer(T element) {
  ensureCapacity(rear + 1);
  elementData[rear++] = element;
 }

 private void ensureCapacity(int minCapacity) {
  //如果数组的原有长度小于目前所需的长度
  int oldCapacity = elementData.length;
  if (minCapacity > oldCapacity) {
   int newCapacity = (oldCapacity * 3) / 2 + 1;
   if (newCapacity < minCapacity)
    newCapacity = minCapacity;
   // minCapacity is usually close to size, so this is a win:
   elementData = Arrays.copyOf(elementData, newCapacity);
  }
 }
 /**
  * @Title: poll
  * @Description: 出队
  * @return
  */
 public T poll() {
  if (isEmpty()) {
   throw new IndexOutOfBoundsException("空队列异常");
  }
  //保留队列的front端的元素的值
  T oldValue = (T) elementData[front];
  //释放队列的front端的元素
  elementData[front++] = null;
  return oldValue;
 }
 /**
  * @Title: peek
  * @Description: 返回队列顶元素,但不删除队列顶元素
  * @return
  */
 public T peek() {
  if (isEmpty()) {
   throw new IndexOutOfBoundsException("空队列异常");
  }
  return (T) elementData[front];
 }
 /**
  * @Title: isEmpty
  * @Description: 判断顺序队列是否为空队列
  * @return
  */
 public boolean isEmpty() {
  return rear == front;
 }
 /**
  * @Title: clear
  * @Description: 清空顺序队列
  */
 public void clear() {
  //将底层数组所有元素赋为null
  Arrays.fill(elementData, null);
  front = 0;
  rear = 0;
 }
 public String toString() {
  if (isEmpty()) {
   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();
  }
 }
}

2. 链式队列的实现

package lang;
import java.io.Serializable;
/**
 * @ClassName: LinkQueue
 * @Description: 链式队列
 * @date 2014年1月21日 下午3:24:38
 * @param <T>
 */
public class LinkQueue<T> implements Serializable{
 /**
  * @Fields serialVersionUID : TODO
  */
 private static final long serialVersionUID = -6726728595616312615L;
 //定义一个内部类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;//保存该链队列中已包含的节点数
 /**
  * <p>Title: LinkQueue </p>
  * <p>Description: 创建空链队列 </p>
  */
 public LinkQueue() {
  //空链队列,front和rear都是null
  front = null;
  rear = null;
 }
 /**
  * <p>Title: LinkQueue </p>
  * <p>Description: 以指定数据元素来创建链队列,该链队列只有一个元素</p>
  */
 public LinkQueue(T element) {
  front = new Node(element, null);
  //只有一个节点,front、rear都指向该节点
  rear = front;
  size++;
 }
 /**
  * @Title: size
  * @Description: 获取顺序队列的大小
  * @return
  */
 public int size() {
  return size;
 }
 /**
  * @Title: offer
  * @Description: 入队
  * @param element
  */
 public void offer(T element) {
  //如果该链队列还是空链队列
  if (front == null) {
   front = new Node(element, null);
   rear = front;//只有一个节点,front、rear都指向该节点
  } else {
   Node newNode = new Node(element, null);//创建新节点
   rear.next = newNode;//让尾节点的next指向新增的节点
   rear = newNode;//以新节点作为新的尾节点
  }
  size++;
 }
 /**
  * @Title: poll
  * @Description: 出队
  * @return
  */
 public T poll() {
  Node oldFront = front;
  front = front.next;
  oldFront.next = null;
  size--;
  return oldFront.data;
 }
 /**
  * @Title: peek
  * @Description: 返回队列顶元素,但不删除队列顶元素
  * @return
  */
 public T peek() {
  return rear.data;
 }
 /**
  * @Title: isEmpty
  * @Description: 判断顺序队列是否为空队列
  * @return
  */
 public boolean isEmpty() {
  return size == 0;
 }
 /**
  * @Title: clear
  * @Description: 清空顺序队列
  */
 public void clear() {
  //将front、rear两个节点赋为null
  front = null;
  rear = null;
  size = 0;
 }
 public String toString() {
  //链队列为空链队列时
  if (isEmpty()) {
   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();
  }
 }
 public static void main(String[] args) {
  LinkQueue<String> queue = new LinkQueue<String>("aaaa");
  //添加两个元素
  queue.offer("bbbb");
  queue.offer("cccc");
  System.out.println(queue);
  //删除一个元素后
  queue.poll();
  System.out.println("删除一个元素后的队列:" + queue);
  //再次添加一个元素
  queue.offer("dddd");
  System.out.println("再次添加元素后的队列:" + queue);
  //删除一个元素后,队列可以再多加一个元素
  queue.poll();
  //再次加入一个元素
  queue.offer("eeee");
  System.out.println(queue);
 }
}

3. 循环队列的实现

package lang;
import java.io.Serializable;
import java.util.Arrays;
/**
 * @ClassName: LoopQueue
 * @Description: 循环队列
 * @date 2014年1月20日 下午3:47:14
 */
public class LoopQueue<T> implements Serializable{
 /**
  * @Fields serialVersionUID : TODO
  */
 private static final long serialVersionUID = -3670496550272478781L;
 private int DEFAULT_SIZE = 10;
 private int capacity;//保存数组的长度
 private Object[] elementData;//定义一个数组用于保存循环队列的元素
 private int front = 0;//队头
 private int rear = 0;//队尾
 //以默认数组长度创建空循环队列
 public LoopQueue() {
  capacity = DEFAULT_SIZE;
  elementData = new Object[capacity];
 }
 //以一个初始化元素来创建循环队列
 public LoopQueue(T element) {
  this();
  elementData[0] = element;
  rear++;
 }
 /**
  * 以指定长度的数组来创建循环队列
  * @param element 指定循环队列中第一个元素
  * @param initSize 指定循环队列底层数组的长度
  */
 public LoopQueue(T element, int initSize) {
  this.capacity = initSize;
  elementData = new Object[capacity];
  elementData[0] = element;
  rear++;
 }
 //获取循环队列的大小
 public int size() {
  if (isEmpty()) {
   return 0;
  }
  return rear > front ? rear - front : capacity - (front - rear);
 }
 //插入队列
 public void add(T element) {
  if (rear == front && elementData[front] != null) {
   throw new IndexOutOfBoundsException("队列已满的异常");
  }
  elementData[rear++] = element;
  //如果rear已经到头,那就转头
  rear = rear == capacity ? 0 : rear;
 }
 //移除队列
 public T remove() {
  if (isEmpty()) {
   throw new IndexOutOfBoundsException("空队列异常");
  }
  //保留队列的rear端的元素的值
  T oldValue = (T) elementData[front];
  //释放队列的rear端的元素
  elementData[front++] = null;
  //如果front已经到头,那就转头
  front = front == capacity ? 0 : front;
  return oldValue;
 }
 //返回队列顶元素,但不删除队列顶元素
 public T element() {
  if (isEmpty()) {
   throw new IndexOutOfBoundsException("空队列异常");
  }
  return (T) elementData[front];
 }
 //判断循环队列是否为空队列
 public boolean isEmpty() {
  //rear==front且rear处的元素为null
  return rear == front && elementData[rear] == null;
 }
 //清空循环队列
 public void clear() {
  //将底层数组所有元素赋为null
  Arrays.fill(elementData, null);
  front = 0;
  rear = 0;
 }
 public String toString() {
  if (isEmpty()) {
   return "[]";
  } else {
   //如果front < rear,有效元素就是front到rear之间的元素
   if (front < rear) {
    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();
   }
   //如果front >= rear,有效元素为front->capacity之间、0->front之间的
   else {
    StringBuilder sb = new StringBuilder("[");
    for (int i = front; i < capacity; i++) {
     sb.append(elementData[i].toString() + ", ");
    }
    for (int i = 0; i < rear; i++) {
     sb.append(elementData[i].toString() + ", ");
    }
    int len = sb.length();
    return sb.delete(len - 2, len).append("]").toString();
   }
  }
 }
 public static void main(String[] args) {
  LoopQueue<String> queue = new LoopQueue<String>("aaaa", 3);
  //添加两个元素
  queue.add("bbbb");
  queue.add("cccc");
  //此时队列已满
  System.out.println(queue);
  //删除一个元素后,队列可以再多加一个元素
  queue.remove();
  System.out.println("删除一个元素后的队列:" + queue);
  //再次添加一个元素,此时队列又满
  queue.add("dddd");
  System.out.println(queue);
  System.out.println("队列满时的长度:" + queue.size());
  //删除一个元素后,队列可以再多加一个元素
  queue.remove();
  //再次加入一个元素,此时队列又满
  queue.add("eeee");
  System.out.println(queue);
 }
}

以上这篇java队列实现方法(顺序队列,链式队列,循环队列)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

您可能感兴趣的文章:

  • java实现队列数据结构代码详解
  • Java自定义实现链队列详解
  • 基于Java数组实现循环队列的两种方法小结
(0)

相关推荐

  • java实现队列数据结构代码详解

    什么是队列结构 一种线性结构,具有特殊的运算法则[只能在一端(队头)删除,在另一端(队尾)插入]. 分类: 顺序队列结构 链式队列结构 基本操作: 入队列 出队列 给出一些应用队列的场景 1):当作业被送到打印机的时候,就可以按到达的顺序排起来,因此每一份作业是队列的节点. 2):售票口的人买票的顺序的按照先来先买的顺序售票. 3):当所有的终端被占用,由于资源有限,来访请求需要放在一个队列中等候. 队列是先进先出的! 我们设置一个叫做LinkQueue<T>的泛型集合类,该类里面有 Node

  • 基于Java数组实现循环队列的两种方法小结

    用java实现循环队列的方法: 1.添加一个属性size用来记录眼下的元素个数. 目的是当head=rear的时候.通过size=0还是size=数组长度.来区分队列为空,或者队列已满. 2.数组中仅仅存储数组大小-1个元素,保证rear转一圈之后不会和head相等.也就是队列满的时候.rear+1=head,中间刚好空一个元素. 当rear=head的时候.一定是队列空了. 队列(Queue)两端同意操作的类型不一样: 能够进行删除的一端称为队头,这样的操作也叫出队dequeue: 能够进行插

  • Java自定义实现链队列详解

    一.写在前面 数据结构中的队列应该是比较熟悉的了,就是先进先出,因为有序故得名队列,就如同排队嘛,在对尾插入新的节点,在对首删除节点.jdk集合框架也是提供也一个Queue的接口.这个接口代表一个队列.顺序队列:ArrayBlockingQueue,LinkedBlockingQueue.(上面两种是足色队列)还有一种是ConcurentLinkedQueue. 底层的实现由数组合链表两种的,数组的实现会有个弊端的,会造成假满的现象,开始的时候,队列为空的时候,对首引用变量个对尾的引用变量都为n

  • java队列实现方法(顺序队列,链式队列,循环队列)

    双向顺序队列ArrayDeque和双向链式队列LinkedList,JDK已经包含,在此略.ArrayDeque包括顺序栈和顺序队列,LinkedList包含链式栈和链式队列.ArrayDeque和LinkedList都是线程不安全的.PriorityQueue优先队列也在JDK. 1.顺序队列的实现 package lang; import java.io.Serializable; import java.util.Arrays; /** * @ClassName: ArrayQueue *

  • Java动态循环队列是如何实现的

    一.队列 1.1 定义 队列 (Queue) 是一种限定性的有序线性表,它只允许在表的一端插入元素,而在另一端删除元素,所以队列具有先进先出 (Fist In Fist Out,缩写为FIFO)的特性. 在队列中,允许插入的一端叫做队尾(rear): 允许删除的一端则称为队头(front). 队列是一个有序列表,可以用数组或是链表来实现. 遵循先进先出的原则.即:先存入队列的数据,要先取出. 1.2 抽象数据类型 数据元素:可以是任意类型的数据,但必须属于同一个数据对象. 关系:队列中数据元素之

  • C语言详解链式队列与循环队列的实现

    目录 队列的实现 链式队列 链式队列的定义 链式队列的实现 循环队列 循环队列的定义 循环队列的实现 队列的实现 队列是一种先进先出(First in First Out)的线性表,简称FIFO.与栈不同,栈是一种后进先出(先进后出)的线性表.在队列中,允许插入的一端称为队尾,允许删除的一端称为队头.假设队列是q=(a1,a2,…,an),那么a1就是队头元素,而an是队尾元素.这样我们就可以删除时,总是从a1开始,而插入时,列在最后.这也比较符合我们通常生活中的习惯,排在第一个的优先出列,最后

  • Java实体类实现链式操作实例解析

    这篇文章主要介绍了Java实体类实现链式操作实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 原来是这么写bean的,单纯的使用get.set方法,再加一个toString package Model; /** * @author: Davion * @date: 2019/12/11 * @description: */ public class User { private Integer id; private String nam

  • Java实现线性表的链式存储

    本文实例为大家分享了Java实现线性表的链式存储,供大家参考,具体内容如下 链表:一种物理存储结构上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的. package algorithm.datastructure.linklist; import java.util.NoSuchElementException; /* * 链表 * 物理存储上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现 * * */ public class LinkedLi

  • js实现封装jQuery的简单方法与链式操作详解

    我用这篇文章来理一理如何用js去实现封装jQuery的简单方法. 本文js实现了下面jquery的几种方法,我将它分为8个小目标 实现$(".box1").click( )方法 实现$("div").click( )方法 考虑$( )中参数的三种情况 实现jq中的on方法 实现链式操作 实现jq中的eq方法 实现jq中的end方法 实现jq中的css方法 有不正确的地方还望大家在评论区指出来,谢谢啦. 1. 实现$(".box1").click(

  • java数据结构循环队列的空满判断及长度计算

    目录 一.假溢出 二.循环队列判断是空是满 三.循环队列的长度计算 四.代码实现 在上一章中,使用了数组模拟了队列.但是留下的问题是,把数据取完后,再往里加数据就不行了. 一.假溢出 这是因为数组的末尾已经被占用了,入队会继续在数组后面增加,于是产生数组越界.但是实际上,数组里是有空闲位置的,这种也可以叫“假溢出”. 为了解决“假溢出”的问题,于是乎有了循环队列. 既然数组后面满了,头部有空,那继续加进来的元素从头开始放即可. 接着上图,这时候有a6入队,于是rear的下标指向a6的下一个元素位

  • Node.js实现链式回调

    由于异步的关系,代码的书写顺序可能和执行顺序并不一样,可能想先执行A再执行B,但由于异步可能B要先于A执行.例如在OC中使用AFnetworking请求数据然后刷新页面,由于网络请求是用block实现的异步方法,所以刷新的时候并没有数据,为了解决这个问题,一般会在请求响应结束在block中刷新页面(这就回出现循环引用的问题,不过node中不会出现). 上面是OC中异步执行中的链式回调,在node.js中也是使用这样的方法在回调中调用方法来实现链式回调. function logCar(car,c

  • JavaScript队列、优先队列与循环队列

    队列是一种遵从先进先出(FIFO)原则的有序集合 队列在尾部添加新元素,从顶部移除元素 队列的理解 队列在我们生活中最常见的场景就是排队了 队列这个名字也已经很通俗易懂了 和栈很像,这不过队列是先入先出的数据结构 队列的前面是队头 队列的后面是队尾 出队从队头出 入队从队尾入 队列的创建 和栈类似,这里我就不就不啰嗦了 同样需要实现一些功能 这里我类比生活中的排队上厕所 向队列中添加元素(进入排队的队伍中) 移除队头元素(队伍最前面的人出队进入厕所) 查看队头元素(查看队伍最前面的人) 判断队列

随机推荐