数据结构——队列

        数据结构中的队列(Queue)是一种常见且重要的数据结构,它遵循先进先出(FIFO, First-In-First-Out)的原则。在Java中,队列可以通过多种方式实现,如使用数组、链表等。

一、队列的基本概念

        队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。队列中的元素按照它们被插入的顺序排列,即先插入的元素会被先删除。队列的主要操作包括入队(enqueue)、出队(dequeue)、查看队头元素(peek/front)以及判断队列是否为空(isEmpty)等。

二、队列的特性

  1. 先进先出(FIFO):队列按照元素被插入的顺序进行排序,先插入的元素会先被删除。
  2. 限制性访问:队列只允许在队尾插入元素,在队头删除元素,不支持随机访问队列中的元素。
  3. 动态扩容:虽然在实际应用中队列的大小通常是有限的,但某些实现(如Java中的LinkedList)可以动态地调整其容量以存储更多的元素。

三、Java中的队列实现

        在Java中,队列可以通过多种方式实现,包括使用Java集合框架(Java Collections Framework)中的Queue接口及其实现类,如LinkedListPriorityQueue等。

import java.util.LinkedList; 
import java.util.Queue; 


public class QueueExample { 
public static void main(String[] args) { 
Queue<Integer> queue = new LinkedList<>(); 


// 入队 
queue.offer(1); 
queue.offer(2); 
queue.offer(3); 


// 查看队头元素 
System.out.println("队头元素: " + queue.peek()); // 输出: 1 


// 出队 
System.out.println("出队元素: " + queue.poll()); // 输出: 1 


// 判断队列是否为空 
System.out.println("队列是否为空: " + queue.isEmpty()); // 输出: false 
} 
}
1. 使用LinkedList实现队列

LinkedList是一个双向链表,但它也实现了Queue接口,因此可以用作队列。LinkedList提供了offer()方法用于入队,poll()方法用于出队,peek()方法用于查看队头元素而不删除它,以及isEmpty()方法用于检查队列是否为空。

import java.util.LinkedList;  
  
public class QueueWithLinkedList {  
  
    private LinkedList<Integer> list = new LinkedList<>();  
  
    // 入队操作  
    public void enqueue(int element) {  
        list.addLast(element); // 使用addLast()方法将元素添加到队尾  
    }  
  
    // 出队操作  
    public Integer dequeue() {  
        if (isEmpty()) {  
            throw new IllegalStateException("Queue is empty");  
        }  
        return list.removeFirst(); // 使用removeFirst()方法移除并返回队首元素  
    }  
  
    // 查看队首元素  
    public Integer peek() {  
        if (isEmpty()) {  
            throw new IllegalStateException("Queue is empty");  
        }  
        return list.getFirst(); // 使用getFirst()方法查看队首元素但不移除  
    }  
  
    // 检查队列是否为空  
    public boolean isEmpty() {  
        return list.isEmpty();  
    }  
  
    // 获取队列的大小  
    public int size() {  
        return list.size();  
    }  
  
    public static void main(String[] args) {  
        QueueWithLinkedList queue = new QueueWithLinkedList();  
  
        // 入队  
        queue.enqueue(1);  
        queue.enqueue(2);  
        queue.enqueue(3);  
  
        // 查看队首元素  
        System.out.println("Front element: " + queue.peek()); // 输出: Front element: 1  
  
        // 出队  
        System.out.println("Dequeued element: " + queue.dequeue()); // 输出: Dequeued element: 1  
        System.out.println("New front element: " + queue.peek()); // 输出: New front element: 2  
  
        // 队列大小  
        System.out.println("Queue size: " + queue.size()); // 输出: Queue size: 2  
    }  
}
2. 使用数组模拟队列

虽然Java标准库中已经提供了多种队列的实现,但了解如何使用数组手动实现队列也是很有帮助的。数组模拟队列时,需要维护两个指针:front指向队头元素的下一个位置(或队头元素的位置,取决于具体实现),rear指向队尾元素的下一个位置。

public class ArrayQueue {  
    private int[] queue; // 存储队列元素的数组  
    private int front; // 队首索引  
    private int rear; // 队尾索引  
    private int size; // 队列当前元素数量  
    private int capacity; // 队列容量  
  
    // 构造函数,初始化队列  
    public ArrayQueue(int capacity) {  
        this.capacity = capacity;  
        this.queue = new int[this.capacity];  
        this.front = 0;  
        this.rear = -1; // 初始时队尾索引设为-1,方便后续直接插入  
        this.size = 0;  
    }  
  
    // 判断队列是否为空  
    public boolean isEmpty() {  
        return size == 0;  
    }  
  
    // 判断队列是否已满  
    public boolean isFull() {  
        return size == capacity;  
    }  
  
    // 入队操作  
    public boolean enqueue(int element) {  
        if (isFull()) {  
            return false; // 队列已满,无法添加  
        }  
        rear = (rear + 1) % capacity; // 循环队列的关键,处理数组越界问题  
        queue[rear] = element;  
        size++;  
        return true;  
    }  
  
    // 出队操作  
    public Integer dequeue() {  
        if (isEmpty()) {  
            return null; // 队列为空,无法移除  
        }  
        int frontElement = queue[front];  
        front = (front + 1) % capacity; // 循环队列的关键,处理数组越界问题  
        size--;  
        return frontElement;  
    }  
  
    // 查看队首元素  
    public Integer front() {  
        if (isEmpty()) {  
            return null; // 队列为空  
        }  
        return queue[front];  
    }  
  
    // 队列大小  
    public int getSize() {  
        return size;  
    }  
  
    public static void main(String[] args) {  
        ArrayQueue queue = new ArrayQueue(5); // 创建一个容量为5的队列  
  
        // 入队  
        queue.enqueue(1);  
        queue.enqueue(2);  
        queue.enqueue(3);  
  
        // 查看队首元素  
        System.out.println("Front element: " + queue.front()); // 输出: Front element: 1  
  
        // 出队  
        System.out.println("Dequeued element: " + queue.dequeue()); // 输出: Dequeued element: 1  
        System.out.println("New front element: " + queue.front()); // 输出: New front element: 2  
  
        // 队列大小  
        System.out.println("Queue size: " + queue.getSize()); // 输出: Queue size: 2  
  
        // 继续入队,直到队列满  
        while (!queue.isFull()) {  
            queue.enqueue(queue.getSize() + 3); // 只是为了展示,实际中可能添加不同的值  
        }  
  
        // 此时队列已满,无法再入队  
        // queue.enqueue(7); // 这将不会成功,因为队列已满  
    }  
}

四、队列的应用场景

队列在计算机科学的各个领域都有广泛的应用,包括但不限于:

  1. 操作系统中的进程调度:进程按照其到达的顺序排队等待处理,调度器会从队列的头部选择下一个要执行的进程。
  2. 网络通信中的消息队列:发送者将消息放入队列的末尾,接收者从队列的头部获取消息进行处理,以确保消息的可靠传递并减少发送者和接收者之间的直接耦合。
  3. 高性能计算中的任务调度:任务可能以非常快的速度同时到达,使用队列来管理任务,确保按照先到达的顺序执行任务。
  4. 缓存淘汰策略:如最近最少使用(LRU)策略,它维护一个队列,最近被访问过的缓存项排在队列的末尾。
  5. 图的搜索算法:如广度优先搜索(BFS),使用队列来维护待访问的节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值