队列的定义
队列(queue)是一种抽象的线性数据结构,是一种只能在一端插入,在另一端获取的有序线性表。队列中第一个插入的元素也是第一个获取的元素,队列的数据到达次序符合“先进先出”(First In First Out, FIFO)的思想。队列常用语说明:
- 入队:向队列中插入元素;
- 出队:从队列中删除一个元素;
- 下溢:对一个空队列执行出队操作;
- 溢出:对一个满队列执行入队操作;
通常认为溢出和下溢是异常。
队列的模型如下:
一般来说,队列有数组和链表两种实现方式。
队列的实现
数组实现队列
一般数组实现
一般数组实现类:
package com.xxliao.datastructure.linerar_list.queue.array;
/**
* @author xxliao
* @description: 数组实现队列
* @date 2024/5/28 14:37
*/
public class ArrayQueue {
//对头索引
public int front;
//队尾索引
public int rear;
//队列容量
public int capacity;
//容器
public Object[] array;
//构造方法,这里暂不验证capacity合法性
public ArrayQueue(int capacity) {
front= -1;
rear = -1;
this.capacity = capacity;
array = new Object[capacity];
}
//判断队列是否为空
public boolean isEmpty() {
return front == -1;
}
//判断队列是否满
public boolean isFull() {
//队列中元素个数(队尾索引加1) 取余 容器容量 等于front(-1,0),代表满,
// rear 和 front 初始的时候 就是 0 % capacity == -1 ,不满
// 开始工作后,添加元素后,front 变为了 0
return ((rear+1)%capacity == front);
}
//入队
public void enQueue(Object data) {
if(isFull()) {
throw new RuntimeException("Queue is Full!");
}
if(isEmpty()) {
//空队列添加
array[++front] = data; // front 变为了 1
rear = front;
}else {
//不是第一次添加,数组元素依次向后移动
for(int i =rear+1; i>0; i--){
array[i] = array[i-1];
}
array[front] = data;
rear++;
}
}
//出队
public Object deQueue() {
if(isEmpty()) {
throw new RuntimeException("Queue is Empty!");
}
Object result = array[rear];
array[rear--] = null;
return result;
}
}
测试类:
package com.xxliao.datastructure.linerar_list.queue.array;
/**
* @author xxliao
* @description: 数组实现队列 测试客户端
* @date 2024/5/28 14:38
*/
public class ArrayQueueTestClient {
public static void main(String[] args) {
//创建队列
ArrayQueue arrayQueue = new ArrayQueue(5);
//一次添加1~5,
arrayQueue.enQueue(1);
arrayQueue.enQueue(2);
arrayQueue.enQueue(3);
arrayQueue.enQueue(4);
arrayQueue.enQueue(5);
//arrayQueue.enQueue(6);
System.out.println(arrayQueue.deQueue());
System.out.println(arrayQueue.deQueue());
System.out.println(arrayQueue.deQueue());
System.out.println(arrayQueue.deQueue());
System.out.println(arrayQueue.deQueue());
//System.out.println(arrayQueue.deQueue());
}
}
测试结果:
动态数组实现
动态数组实现类:
package com.xxliao.datastructure.linerar_list.queue.array;
/**
* @author xxliao
* @description: 动态数组实现队列
* @date 2024/5/28 14:50
*/
public class DynamicArrayQueue {
//对头索引
public int front;
//队尾索引
public int rear;
//队列容量
public int capacity;
//容器
public Object[] array;
//默认队列容量为10
public final int DEFAULT_CAPACITY = 16;
//构造方法,无参
public DynamicArrayQueue() {
front= -1;
rear = -1;
capacity = DEFAULT_CAPACITY;
array = new Object[capacity];
}
//构造方法,有参,这里暂不验证capacity合法性
public DynamicArrayQueue(int capacity) {
front= -1;
rear = -1;
this.capacity = capacity;
array = new Object[capacity];
}
//判断队列是否为空
public boolean isEmpty() {
return front == -1;
}
//判断队列是否为空
private boolean isFull() {
//队列中元素个数(队尾索引加1) 取余 容器容量 等于 0,代表满
return ((rear+1)%capacity == front);
}
//队列扩容
private void resizeQueue() {
capacity = capacity + (capacity >> 1);
Object[] oldArray = array;
array = new Object[capacity];
for (int i = 0; i < oldArray.length; i++) {
array[i] = oldArray[i];
}
}
//入队
public void enQueue(Object data) {
if(isFull()) {
//当前队列满对,扩容
resizeQueue();
}
if(isEmpty()) {
//空队列添加
array[++front] = data;// front -> 1
rear = front;
}else {
//不是第一次添加,数组元素一次向后移动
for(int i =rear+1; i>0; i--){
array[i] = array[i-1];
}
array[front] = data;
rear++;
}
}
//出队
public Object deQueue() {
if(isEmpty()) {
throw new RuntimeException("Queue is Empty!");
}
Object result = array[rear];
array[rear--] = null;
return result;
}
}
测试类:
package com.xxliao.datastructure.linerar_list.queue.array;
/**
* @author xxliao
* @description: 动态数组实现队列 测试客户端
* @date 2024/5/28 14:52
*/
public class DynamicArrayQueueTestClient {
public static void main(String[] args) {
//创建队列,默认容量10
DynamicArrayQueue arrayQueue = new DynamicArrayQueue();
//一次添加1~17
for (int i = 1; i <= 17; i++) {
arrayQueue.enQueue(i);
}
for (int i = 1; i <= 17; i++) {
System.out.print(arrayQueue.deQueue()+" ");
}
}
}
控制台输出:
链表实现队列
链表实现队列 节点类
package com.xxliao.datastructure.linerar_list.queue.linked_list;
/**
* @author xxliao
* @description: 链表实现队列 节点类
* @date 2024/5/28 12:31
*/
public class Node {
//存储数据
protected Object data;
//下个节点
public Node next;
//构造
public Node(Object data) {
this.data = data;
}
//toString查看输出
public String toString() {
return "Node [data=" + data + ", next=" + next + "]";
}
}
链表实现队列 实现类
package com.xxliao.datastructure.linerar_list.queue.linked_list;
/**
* @author xxliao
* @description: 链表实现队列
* @date 2024/5/28 14:56
*/
public class LinkedListQueue {
//对头索引
public Node front;
//队尾索引
public Node rear;
//队列元素数量
public int size;
//构造方法
public LinkedListQueue() {
front= null;
rear = null;
size = 0;
}
//判断队列是否为空
public boolean isEmpty() {
return front == null;
}
//入队
public void enQueue(Object data) {
Node newNode = new Node(data);
if(isEmpty()) {
//空队列添加
front = rear = newNode;
}else {
rear.next = newNode;
rear = newNode;
}
size++;
}
//出队
public Object deQueue() {
if(isEmpty()) {
throw new RuntimeException("Queue is Empty!");
}
Object result = front.data;
if(front.next == null) {
//只有一个元素
front = rear = null;
}else {
front = front.next;
}
size--;
return result;
}
//获取元素个数
public int size() {
return size;
}
}
测试类:
package com.xxliao.datastructure.linerar_list.queue.linked_list;
/**
* @author xxliao
* @description: 链表实现队列 测试客户端
* @date 2024/5/28 14:57
*/
public class LinkedListQueueTextClient {
public static void main(String[] args) {
// 创建队列
LinkedListQueue linkQueue = new LinkedListQueue();
//一次添加1~25
for (int i = 1; i <= 25; i++) {
linkQueue.enQueue(i);
}
System.out.println("size is" + linkQueue.size);
for (int i = 1; i <= 25; i++) {
System.out.print(linkQueue.deQueue()+" ");
}
}
}
测试结果:
完整代码
https://github.com/xxliao100/datastructure_algorithms.git