java数据结构之自定义队列
一、队列的特点
1、队列是线性结构
2、先进先出,先进入队列的排在队列前端,会比后进队列的先出队列。FIFO
二、通过数组来实现队列
//自己实现数组队列,队列的特定就是先进先出 public class MyArrayQueue<E> { //用数组来保存 private Object[] queue; //队列容量 private int capacity; //队列中元素的个数 private int size; //队列头部元素对应的下标 private int head; //队列的尾部的下一个位置下标 private int tail; public MyArrayQueue(int capacity){ this.capacity = capacity; this.queue = new Object[capacity]; } //将元素加入到队列的队尾,如果队列空间不足,抛出异常 public boolean add(E e) throws Exception{ //先确定空间是否足够,已经满了就抛出异常 if(size == capacity){ throw new Exception("queue full"); } //没满就加入到队尾 queue[tail] = e; //计算新的队尾 tail = (tail+1) % capacity; size ++; return true; } //返回并删除队列头部的元素,如果队列为空,抛出异常 public E remove() throws NoSuchElementException{ //判断是否为空,为空则报错 if(size == 0){ throw new NoSuchElementException(); } E removed = elementData(head); //将头部元素设置为null queue[head] = null; //重新计算head的值 head = (head+1) % capacity; size -- ; return removed; } //将元素加入到队尾,如果队列已经满了,返回false public boolean offer(E e){ //先确定空间是否足够,已经满了就返回false if(size == capacity){ return false; } //没满就加入到队尾 queue[tail] = e; //计算新的队尾 tail = (tail+1) % capacity; size ++; return true; } //返回并删除队列头部的元素,如果队列为空,返回null public E poll(){ //判断是否为空,为空则返回null if(size == 0){ return null; } E removed = elementData(head); //将头部元素设置为null queue[head] = null; //重新计算head的值 head = (head+1) % capacity; size -- ; return removed; } //返回队列头部的元素,如果队列为空,抛出异常 public E element(){ //判断是否为空,为空则报错 if(size == 0){ throw new NoSuchElementException(); } E e = elementData(head); return e; } //返回队列头部的元素,如果队列为空,返回null public E peek(){ //判断是否为空,为空则返回null if(size == 0){ return null; } E e = elementData(head); return e; } @SuppressWarnings("unchecked") private E elementData(int index) { return (E) queue[index]; } }
三、通过链表来实现队列
//使用链表来实现队列 public class MyLinkedQueue<E> { //节点,保存元素信息,通过next指向下一个节点,形成单链表 private static class Node<E>{ E item; Node<E> next;//下一个节点 Node(E e, Node<E> next){ this.item = e; this.next = next; } } //容量 private int capacity; //元素个数 private int size; //头节点 private Node<E> head; //尾节点 private Node<E> tail; //构造函数 public MyLinkedQueue(int capacity){ this.capacity = capacity; } //将元素加入到队列的队尾,如果队列空间不足,抛出异常 public boolean add(E e) throws Exception{ //先确定空间是否足够,已经满了就抛出异常 if(size == capacity){ throw new Exception("queue full"); } //创建一个新的节点,然后添加到队列尾部 Node<E> node = new Node<E>(e,null); if(size == 0){//如果队列为空 head = tail = node; }else{//如果队列中已经有节点了 tail.next = node; tail = node; } size ++; return true; } //返回并删除队列头部的元素,如果队列为空,抛出异常 public E remove() throws NoSuchElementException{ //判断是否为空,为空则报错 if(size == 0){ throw new NoSuchElementException(); } E e = head.item; head.item = null; //方便GC //将head指向下一个节点 head = head.next; if(head == null){//删除后队列为空,头节点和尾节点都为null tail = null; } size -- ; return e ; } //将元素加入到队尾,如果队列已经满了,返回false public boolean offer(E e){ //先确定空间是否足够,已经满了就返回false if(size == capacity){ return false; } //创建一个新的节点,然后添加到队列尾部 Node<E> node = new Node<E>(e,null); if(size == 0){//如果队列为空 head = tail = node; }else{//如果队列中已经有节点了 tail.next = node; tail = node; } size ++; return true; } //返回并删除队列头部的元素,如果队列为空,返回null public E poll(){ //判断是否为空,为空则返回null if(size == 0){ return null; } E e = head.item; head.item = null; //方便GC //将head指向下一个节点 head = head.next; if(head == null){//删除后队列为空,头节点和尾节点都为null tail = null; } size -- ; return e ; } //返回队列头部的元素,如果队列为空,抛出异常 public E element(){ //判断是否为空,为空则报错 if(size == 0){ throw new NoSuchElementException(); } E e = head.item; return e; } //返回队列头部的元素,如果队列为空,返回null public E peek(){ //判断是否为空,为空则返回null if(size == 0){ return null; } E e = head.item ; return e; } }