- 定义:队列是一种特殊的线性数据结构,它的特点是先进先出(FIFO,First In First Out)。
- 循环队列的实现
- 定义:循环队列是一种线性数据结构,其操作表现基于FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。
- 数组实现
static class QueueArray{ private int maxSize;//定义数组最大容量 private int front;//定义队列头 private int rear;//定义队列尾 private int[] data;//数据 //初始化队列(构造器) //初始化队列 public QueueArray(int maxSize) { this.maxSize = maxSize; this.front = 0; this.rear = 0; this.data=new int[maxSize]; } //1.判断队列是否满 public boolean isFull(){ return (rear+1)%maxSize==front; } //2.判断队列是否为空 public boolean isEmpty(){ return rear==front; } //3.入队 public void addQueue(int value){ if (isFull()){ System.out.println("队列已满"); return; } data[rear]=value; rear=(rear+1)%maxSize; } //4.出队 public int getQueue(){ if (isEmpty()){ throw new RuntimeException("队列为空"); } //获取队头 int value = data[front]; front=(front+1)%maxSize; return value; } //5.显示队列所有数据 public void showQueue(){ if (isEmpty()){ throw new RuntimeException("队列为空"); } System.out.println(Arrays.toString(data)); } //6.显示队列头部数据 public int showHead(){ if (isEmpty()){ throw new RuntimeException("队列为空"); } return data[front]; } }
- 链表实现
public class Node { int value; Node next; public Node(int value) { this.value = value; this.next=null; } } public class CircularLinkedQueue { private Node front; private Node rear; private int size; private int currentSize; public CircularLinkedQueue(int size) { front = null; rear = null; this.size = size; currentSize=0; } //判空 public boolean isEmpty(){ return currentSize==0; } //判满 public boolean isFull(){ return size==currentSize; } //入队 public boolean enQueue(int value){ if (isFull()){ System.out.println("队列已满,无法入队"); return false; } Node newNode = new Node(value); if(isEmpty()){ front=newNode; rear=newNode; }else { rear.next=newNode; rear=newNode; } currentSize++; return true; } //出队 public int dequeue(){ if (isEmpty()){ System.out.println("队列为空,无法出队"); return -1; } int value = front.value; //最后一个节点出队 if (front==rear){ rear=null; } front=front.next; currentSize--; return value; } }
- 数组实现中队满浪费空间处理
- 新增currentSize字段记录队列当前容量
//判断队列是否满 public boolean isFull(){ return currentSize==maxSize; } //判断队列是否为空 public boolean isEmpty(){ return currentSize==0; } //入队 public void addQueue(int value){ if (isFull()){ System.out.println("队列已满"); return; } data[rear]=value; currentSize++; rear=(rear+1)%maxSize; } //出队 public int getQueue(){ if (isEmpty()){ throw new RuntimeException("队列为空"); } //获取队头 int value = data[front]; front=(front+1)%maxSize; currentSize--; return value; }
- 新增currentSize字段记录队列当前容量
- 双端队列的实现
- 定义:双端队列是一种特殊的队列,它允许元素从两端被插入和删除。
- 数组实现
public class DoubleQueue { private int[] data; private int front; private int rear; private int size; private int currentSize; public DoubleQueue(int size){ this.size=size; this.data=new int[size]; this.currentSize=0; front=0; rear=0; } //判空 public boolean isEmpty(){ return currentSize==0; } //判满 public boolean isFull(){ return currentSize==size; } //队头插入 public boolean insertFront(int item){ if (isFull()){ System.out.println("队满"); return false; } //队列为空 if (isEmpty()){ data[front]=item; currentSize++; //队列不为空 }else { front=(front-1+size)%size; data[front]=item; currentSize++; } return true; } //队尾插入 public boolean insertRear(int item){ if (isFull()){ System.out.println("队满"); return false; } data[rear]=item; currentSize++; rear=(rear+1)%size; return true; } //队头删除 public boolean deleteFront(){ if (isEmpty()){ System.out.println("队空"); return false; } front=(front+1)%size; currentSize--; return true; } //队尾删除 public boolean deleteRear(){ if (isEmpty()){ System.out.println("队空"); return false; } rear=(rear-1+size)%size; currentSize--; return true; } }
- 链表实现
public class DequeNode { public int data; public DequeNode prev; public DequeNode next; public DequeNode(int data) { this.data = data; this.prev=null; this.next=null; } } public class LinkedDoubleDeque { private DequeNode head; private DequeNode tail; public LinkedDoubleDeque() { head = null; tail = null; } //队头添加元素 public void addFirst(int value){ DequeNode newNode = new DequeNode(value); if (head == null){ head = newNode; tail = newNode; }else { newNode.next = head; head.prev = newNode; head = newNode; } } //队尾添加元素 public void addLast(int value){ DequeNode newNode = new DequeNode(value); if (tail==null){ head=newNode; tail=newNode; }else { newNode.prev=tail; tail.next=newNode; tail=newNode; } } //队头删除元素 public int removeFirst(){ if (head==null){ throw new RuntimeException("队列为空"); } int value = head.data; head=head.next; //删除的是最后的数据 if (head==null){ tail=null; }else { head.prev=null; } return value; } //队尾删除元素 public int removeLast(){ if (tail==null){ throw new RuntimeException("队列为空"); } int value = tail.data; tail=tail.prev; //删除的是最后的数据 if (tail==null){ head=null; }else { tail.next=null; } return value; } }
- Java 中可以用来实现队列的数据结构
- ArrayDeque
public class ArrayDequeDemo { private ArrayDeque<Integer> deque; public ArrayDequeDemo() { this.deque =new ArrayDeque<>(); } //判断队空 public boolean isEmpty() { return deque.isEmpty(); } //获取队头 public Integer getFront() { return deque.peekFirst(); } //获取队尾 public Integer getRear() { return deque.peekLast(); } //获取队列长度 public int size() { return deque.size(); } //添加到队头 public void addFront(Integer e) { deque.addFirst(e); } //添加到队尾 public void addRear(Integer e) { deque.addLast(e); } //删除队头 public void removeFront() { deque.removeFirst(); } //删除队尾 public void removeRear() { deque.removeLast(); } }
- getFirst 方法和peekFirst方法区别
- peekFirst检索但不删除此双端队列的最后一个元素,如果此双端队列为空,则返回 null 。
- getFirst方法与peekFirst的不同之处仅在于,如果此双端队列为空,则会抛出NoSuchElementException异常。
- getFirst 方法和peekFirst方法区别
- LinkedList:LinkedList 和 ArrayDeque 都是 Java 中的类,都可以用来实现队列。LinkedList 使用双向链表实现,而 ArrayDeque 使用可变大小的数组实现。实现方法基本类似。
- PriorityBlockingQueue:这是一个优先级队列,它基于堆实现。
- ArrayDeque
- 数组队列和链表队列的优缺点以及使用场景
- 数组队列
- 优点
- 支持随机访问:可以通过索引直接访问队列中的任意元素。
- 快速出队:出队操作(dequeue)的时间复杂度为 O(1)。
- 缺点
- 长度固定:队列长度固定,当队列满时,无法添加新元素,需要动态扩容。
- 内存占用高:需要一块连续的内存空间来存储队列元素,扩容时可能需要重新分配内存
- 使用场景:需要快速出队和随机访问元素的场景,如生产者-消费者问题、优先级队列等。
- 优点
- 链表队列
- 优点
- 长度可变:队列长度可以动态变化,不会因为固定长度而限制队列的大小。
- 快入队和出队:入队(enqueue)和出队(dequeue)操作的时间复杂度为 O(1)。
- 缺点
- 不支持随机访问:不能通过索引直接访问队列中的元素。
- 内存占用高:每个节点需要存储数据和指向下一个节点的引用,内存占用相对较高。
- 使用场景:需要动态调整队列长度的场景,如消息队列、任务队列等。
- 优点
- 数组队列
数据结构-队列
![](https://img-home.csdnimg.cn/images/20240611030827.png)