有借鉴的地方 但是忘记哪个博客了 如果侵权请联系我
package QueueDemo;
public interface Queue<E> {
boolean isEmpty();
void push(E data);
E pop();
E peek();
void clear();
int length();
}
1. 队列的线性存储
package QueueDemo.SequenceQueueTest;
import QueueDemo.Queue;
import java.util.Arrays;
/**
* @description 数组构建队列
*/
public class SequenceQueue<E> implements Queue<E> {
// 队列默认长度
private int DEFAULT_SIZE = 10;
// 用来保存队列元素的数组
private Object[] elementData;
// 保存数组的长度。
private int capacity;
// 队列头元素位置
private int front = 0;
// 队列尾元素位置
private int rear = 0;
/**
* 初始化数组长度和数组
*/
public SequenceQueue() {
this.capacity = DEFAULT_SIZE;
elementData = new Object[capacity];
}
/**
* 以一个初始元素来构建队列
*
* @param value
*/
public SequenceQueue(E value) {
this();
elementData[0] = value;
rear++;
}
/**
* 以指定长度的数组来创建队列
*
* @param value 指定顺序中的第一个元素
* @param initSize 数组长度
*/
public SequenceQueue(E value, int initSize) {
this.capacity = initSize;
elementData = new Object[capacity];
elementData[0] = value;
rear++;
}
/**
* 判断队列是否为空
*
* @return
*/
@Override
public boolean isEmpty() {
return front == rear;
}
/**
* 入队
*
* @param data
* @throws IndexOutOfBoundsException
*/
@Override
public void push(E data) {
// 检查队列是否已经满了
checkQueueIsFull();
elementData[rear++] = data;
}
/**
* 出队,推出元素
*
* @return
* @throws IndexOutOfBoundsException
*/
@Override
@SuppressWarnings("unchecked")
public E pop() {
// 检查队列是否为空
checkQueueIsEmpty();
E oldValue = (E) elementData[front];
// 释放队列已经出栈的元素
elementData[front++] = null;
return oldValue;
}
/**
* 推出元素但不出队
*
* @return
* @throws IndexOutOfBoundsException
*/
@Override
@SuppressWarnings("unchecked")
public E peek() {
// 检查队列是否为空
checkQueueIsEmpty();
return (E) elementData[front];
}
/**
* 清空队列中的元素
*/
@Override
public void clear() {
// 将所有元素赋值为null
Arrays.fill(elementData, null);
front = rear = 0;
}
/**
* 获取顺序队列的大小
*
* @return
*/
@Override
public int length() {
return rear - front;
}
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();
}
}
/**
* 判断队列是否为空,若为空则抛出IndexOutOfBoundsException
*/
private void checkQueueIsEmpty() {
if (isEmpty()) {
throw new IndexOutOfBoundsException("队列为空");
}
}
/**
* 判断队列是否已经满了,若满了则抛出IndexOutOfBoundsException
*/
private void checkQueueIsFull() {
if (rear > capacity - 1) {
throw new IndexOutOfBoundsException("队列已经满了");
}
}
}
package QueueDemo.SequenceQueueTest;
public class SequenceQueuetest {
public static void main(String[] args) {
SequenceQueue<Integer> queue = new SequenceQueue<>();
// 依次将元素入队
int[] data = new int[]{1,2,3,4,5};
initData(queue,data);
System.out.println("----------------- 打印队列: ----------------------");
System.out.println(queue);
System.out.println("访问队列的front元素:" + queue.peek());
System.out.println("移除队列的front元素:" + queue.pop());
System.out.println("移除队列的front元素:" + queue.pop());
System.out.println("两次调用remove方法后的队列:" + queue);
}
private static void initData(SequenceQueue<Integer> queue, int[] data) {
for (int x : data) {
queue.push(x);
}
}
}
2. 循环队列
package QueueDemo.LoopQueueTest;
import QueueDemo.Queue;
import java.util.Arrays;
/**
* @description 循环队列
*/
public class LoopQueue<E> implements Queue<E> {
// 队列默认长度
private int DEFAULT_SIZE = 10;
// 用来保存队列元素的数组
private Object[] elementData;
// 保存数组的长度。
private int capacity;
// 队列头元素位置
private int front = 0;
// 队列尾元素位置
private int rear = 0;
public LoopQueue() {
this.capacity = DEFAULT_SIZE;
elementData = new Object[capacity];
}
//以一个初始元素来构建循环队列
public LoopQueue(E data) {
this();
elementData[0] = data;
rear++;
}
//以初始元素和初始长度来构建循环队列
public LoopQueue(E data, int initSize) {
this.capacity = initSize;
elementData = new Object[capacity];
elementData[0] = data;
rear++;
}
//判断队列是否为空
@Override
public boolean isEmpty() {
return rear == front
&& elementData[rear] == null;
}
//入队
@Override
public void push(E data) {
// 判断队列是否已经满了
checkQueueIsFull();
elementData[rear++] = data;
// rear到头则rear转头
rear = rear == capacity ? 0 : rear;
}
//出队并删除头元素
@Override
@SuppressWarnings("unchecked")
public E pop() {
// 判断队列是否为空
checkQueueIsEmpty();
E oldValue = (E) elementData[front];
elementData[front++] = null;
// front到头则front转头
front = front == capacity ? 0 : front;
return oldValue;
}
/**
* 查找队列的第一个元素
*
* @return
* @throws IndexOutOfBoundsException
*/
@Override
@SuppressWarnings("unchecked")
public E peek() {
// 判断队列是否为空
checkQueueIsEmpty();
return (E) elementData[front];
}
//清空队列
@Override
public void clear() {
Arrays.fill(elementData, null);
front = rear = 0;
}
// 获取循环队列的大小
@Override
public int length() {
if (isEmpty()) {
return 0;
} else {
return rear - front > 0 ? rear - front
: capacity - (front - rear);
}
}
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();
}
}
}
/**
* 判断队列是否为空,若为空则抛出IndexOutOfBoundsException
*/
private void checkQueueIsEmpty() {
if (isEmpty()) {
throw new IndexOutOfBoundsException("队列为空");
}
}
/**
* 判断队列是否已经满了,若满了则抛出IndexOutOfBoundsException
*/
private void checkQueueIsFull() {
if (rear == front && elementData[front] != null) {
throw new IndexOutOfBoundsException("队列已经满了");
}
}
}
package QueueDemo.LoopQueueTest;
public class LoopQueuetest {
public static void main(String[] args) {
LoopQueue<Integer> queue
= new LoopQueue<>(1,3);
// 添加两个元素
queue.push(2);
queue.push(3);
// 此时队列已满
System.out.println(queue);
// 删除一个元素后,队列可以再多加一个元素
queue.pop();
System.out.println("删除一个元素后的队列:" + queue);
// 再次添加一个元素,此时队列又满
queue.push(4);
System.out.println(queue);
System.out.println("队列满时的长度:" + queue.length());
// 查询front元素
System.out.println("查询front元素:" + queue.peek());
}
}
3. 队列的链式存储
package QueueDemo.LinkQueueTest;
import QueueDemo.Queue;
public class LinkQueue<E>implements Queue<E> {
private static class Node<E> {
E item;
Node<E> next;
public Node() {
}
public Node(E item, Node<E> next) {
this.item = item;
this.next = next;
}
}
private Node<E> front;
private Node<E> rear;
//队列包含的结点数
private int size;
public LinkQueue() {
front = null;
rear = null;
}
//以特定的数据来构造链表队列的头结点
public LinkQueue(E data) {
front = new Node<>(data, null);
rear = front;
size++;
}
@Override
public boolean isEmpty() {
return size == 0;
}
//入队
@Override
public void push(E data) {
Node<E> newNode = new Node<>(data, null);
// 当前队列为空
if (isEmpty()) {
front = newNode;
rear = newNode;
} else {
// 队列存在元素
// 尾结点的next指向新结点
rear.next = newNode;
// 新结点成为新的尾结点
rear = newNode;
}
size++;
}
//出队,并删除头元素
@Override
public E pop() {
// 检测队列是否空
checkQueueIsEmpty();
Node<E> oldFront = front;
front = front.next;
oldFront.next = null;
size--;
return oldFront.item;
}
//查找队列的front元素
@Override
public E peek() {
// 检测队列是否空
checkQueueIsEmpty();
return front.item;
}
@Override
public void clear() {
front = null;
rear = null;
size = 0;
}
/**
* 返回队列长度
*
* @return
*/
@Override
public int length() {
return size;
}
@Override
public String toString() {
if (isEmpty()) {
return "[]";
} else {
StringBuilder sb = new StringBuilder("[");
for (Node<E> cur = front; cur != null; cur = cur.next) {
sb.append(cur.item.toString() + ", ");
}
int len = sb.length();
return sb.delete(len - 2, len).append("]").toString();
}
}
/**
* 判断队列是否为空,若为空则抛出IndexOutOfBoundsException
*/
private void checkQueueIsEmpty() {
if (isEmpty()) {
throw new IndexOutOfBoundsException("队列为空");
}
}
}
package QueueDemo.LinkQueueTest;
public class LinkQueuetest {
public static void main(String[] args) {
LinkQueue<Integer> queue = new LinkQueue<>();
// 添加两个元素
queue.push(1);
queue.push(2);
queue.push(3);
System.out.println("打印队列:" + queue);
// 删除一个元素
System.out.println("删除一个元素,该元素为:" + queue.pop());
System.out.println("删除一个元素后的队列:" + queue);
// 输出当前队列的第一个元素
System.out.println("输出当前队列的第一个元素:" + queue.peek());
System.out.println("打印队列:" + queue);
}
}