Queue的使用

本文介绍Java中队列(Queue)的概念及其实现,包括FIFO(先进先出)特性的LinkedList实现,以及使用PriorityQueue实现优先级队列的方法。通过实例展示了如何创建队列、插入和移除元素等基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Queue

FIFO(First-in,First-out)
Queue在并发编程中十分重要。
LinkedList有支持Queue行为的方法,它实现了Queue接口,所以LinkedList可以作为Queue实现。

方法

  • offer():在Queue尾插入元素,如果插入失败返回false;
  • peek():返回Queue头元素(不删除),如果没有返回null;
  • element():返回Queue头元素(不删除),如果没有抛出NoSuchElementException()异常;
  • poll():删除并返回头元素,如果没有返回null;
  • remove():删除并返回头元素,如果没有抛出NoSuchElementException()异常;

例:

import java.util.*;

public class QueueDemo {

    public static void printQ(Queue queue) {
        while (queue.peek() != null) {
            System.out.print(queue.remove() + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<Integer>();
        Random rand = new Random(47);
        for (int i = 0; i < 10; i++) {
            queue.offer(rand.nextInt(i + 10));
        }
        printQ(queue);
        Queue<Character> qc = new LinkedList<Character>();
        for (char c : "HelloWorld".toCharArray())
            qc.offer(c);
        printQ(qc);
    }
}

PriorityQueue(待续)

通过自己的comparator,改变元素的顺序。
当调用peek(),remove(),poll()得到的是优先级最高的元素。

Integer,String,Charator应用于PriorityQueue是因为它们有自然顺序。如果想要在PriorityQueue中加入自己的对象,就必须包含额外的产生自然顺序的函数或者提供自己的Comparator()。

### 队列(Queue)的实现方式 队列是一种遵循先进先出(FIFO,First In First Out)原则的数据结构。它可以使用数组或链表来实现,每种方法都有其特点和适用场景。 #### 使用数组实现队列 当使用数组实现队列时,通常需要定义两个索引变量 `front` 和 `rear` 来分别表示队首和队尾的位置。为了提高性能并解决数组空间浪费的问题,可以引入循环队列的概念[^2]。以下是基于数组实现队列的主要操作: - **初始化**:分配固定大小的空间给数组,并设置初始状态。 - **入队 (`push`):将新元素加入到队尾位置 `rear` 并更新 `rear` 的值。 - **出队 (`pop`):移除位于队首位置 `front` 的元素,并更新 `front` 的值。 - **判空 (`empty`):检查队列是否为空,即 `front == rear`。 - **获取队首元素 (`front`):返回当前队首元素的内容。 - **获取队尾元素 (`back`):返回当前队尾元素的内容。 - **获取队列长度 (`size`):计算队列中的有效元素数量。 ```c #define MAX_SIZE 100 typedef struct { int data[MAX_SIZE]; int front; int rear; } Queue; void QueueInit(Queue* pq) { pq->front = pq->rear = 0; } bool QueueEmpty(Queue* pq) { return pq->front == pq->rear; } void QueuePush(Queue* pq, int x) { if ((pq->rear + 1) % MAX_SIZE == pq->front) { // 判断队满 printf("Queue is full\n"); return; } pq->data[pq->rear] = x; pq->rear = (pq->rear + 1) % MAX_SIZE; } int QueueFront(Queue* pq) { return pq->data[pq->front]; } int QueueBack(Queue* pq) { return pq->data[(pq->rear - 1 + MAX_SIZE) % MAX_SIZE]; } void QueuePop(Queue* pq) { if (QueueEmpty(pq)) { printf("Queue is empty\n"); return; } pq->front = (pq->front + 1) % MAX_SIZE; } ``` #### 使用链表实现队列 相比于数组,链表实现队列更加灵活,因为它不需要预先指定固定的容量。通过维护指向头结点和尾节点的指针,可以在常量时间内完成入队和出队的操作[^3]。下面是链表实现队列的关键函数: - **初始化**:创建一个空的双向链表作为队列的基础结构。 - **入队 (`push`):在链表尾部添加新的节点。 - **出队 (`pop`):删除链表头部的第一个节点。 - **判空 (`empty`):检测链表是否有任何节点存在。 - **获取队首元素 (`front`):返回链表第一个节点保存的数据。 - **获取队尾元素 (`back`):返回链表最后一个节点保存的数据。 - **获取队列长度 (`size`):遍历整个链表统计其中的有效节点数目。 ```c typedef struct Node { int data; struct Node* next; } QueueNode; typedef struct { QueueNode* head; QueueNode* tail; } Queue; void QueueInit(Queue* pq) { pq->head = NULL; pq->tail = NULL; } bool QueueEmpty(Queue* pq) { return pq->head == NULL; } void QueuePush(Queue* pq, int x) { QueueNode* newNode = malloc(sizeof(QueueNode)); newNode->data = x; newNode->next = NULL; if (!QueueEmpty(pq)) { pq->tail->next = newNode; } else { pq->head = newNode; } pq->tail = newNode; } int QueueFront(Queue* pq) { assert(pq && !QueueEmpty(pq)); return pq->head->data; } int QueueBack(Queue* pq) { assert(pq && !QueueEmpty(pq)); return pq->tail->data; } void QueuePop(Queue* pq) { if (QueueEmpty(pq)) { printf("Queue is empty\n"); return; } QueueNode* tmp = pq->head; pq->head = pq->head->next; free(tmp); if (pq->head == NULL) { pq->tail = NULL; } } ``` 上述代码展示了如何利用链表高效地管理动态变化的队列数据[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值