队列和优先队列

文章介绍了Java中的队列和优先队列数据结构,包括Queue接口、LinkedList实现的Deque双端队列以及PriorityQueue类。队列遵循先进先出原则,而优先队列允许按优先级访问元素。LinkedList适合作为队列使用,支持两端插入和移除。PriorityQueue则可以自定义排序规则,最小值具有最高优先级。

队列和优先队列

队列是一种先进先出的结构。元素被追加到队列末尾,然后从队列列头删除;优先队列中,元素被赋予优先级。访问元素时,最高优先级的元素先被删除

Queue接口

该接口继承java.util.Collection,加入了插入、提取和检验操作:

《interface》 java.util.Queue
offer(element: E):boolean插入一个元素到队列中
poll():E获取并移除队列的头元素,若队头为空返回null
remove(): E获取并移除队列的头元素,队头为空抛出异常
peek(): E获取但不移除头元素,若队列为空返回null
element(): E获取但不移除头元素,队列为空抛出异常

双端队列Deque和链表LinkedList

LinkedList实现了Deque接口,Deque又继承了Queue接口;LinkedList适合用于队列操作,它可以高效地在列表的两端插入和移除元素

Deque支持在两端插入和删除元素,增加了相关的方法

  • addFirst(e)
  • removeFirst()
  • addLast()
  • removeLast()
  • getFirst()
  • getLast()
public class TestDeque {

    public static void main(String[] args) {

        LinkedList<String> deque = new LinkedList<>();
        deque.add("张三");
        deque.add("李四");
        deque.add("王五");
        deque.add("赵六");
        deque.addFirst("刘伟");
        deque.removeLast();
        deque.removeFirst();
        System.out.println("第一个元素是:" + deque.getFirst() + " " + "最后一个元素是:" + deque.getLast());
    }

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6px3BLgX-1684848863528)(C:\Users\26399\AppData\Roaming\Typora\typora-user-images\image-20230523210250400.png)]

PriorityQueue类实现了一个优先队列,默认情况下优先队列使用Comparable以元素的自然顺序排序;拥有最小数值的元素被赋予最高优先级,因此最先从列表中删除。几个元素具有相同的最高优先级,随机选择一个;也可以使用PriorityQueue(initialCapacity, comparator) 构造方法指定一个顺序

java.util.PriorityQueue
PriorityQueue()创建一个初始容量为11的默认优先队列
PriorityQueue(initialCapacity: int)创建一个初始容量为指定值的默认优先队列
PriorityQueue(c:Collection<? extends E>)使用指定合集创建一个优先队列
PriorityQueue(initialCapacity: int, comparator<? extends E>)创建一个指定初始容量和比较器的优先队列
### 队列优先队列的概念 #### 队列概述 队列是一种遵循先进先出(FIFO, First In First Out)原则的线性数据结构。这意味着最早进入队列的元素会最先被移除。为了更高效地利用存储空间并解决顺序队列中的“假溢出现象”,通常采用循环队列的形式,即一种头尾相接的顺序存储结构[^2]。 #### 优先队列定义 不同于普通队列按照加入顺序处理元素的方式,优先队列根据预先设定的关键字来决定哪个元素应当首先被取出。这种关键字可以代表任务的重要性或其他形式的权重,在某些应用场景下非常有用。具体来说,当执行`DeleteMin`操作时,将会找到、返回并移除具有最低关键字值的那个成员;而通过`Insert`则可向其中添加新的项目[^4]。 ### 实现方式对比 #### 常规队列入门级实现 对于简单的队列而言,可以通过数组或链表来进行构建。然而,考虑到性能因素以及内存管理上的便利性,这里推荐使用固定大小的数组作为基础容器,并配合两个指针分别指向当前头部位置与尾部位置以追踪有效范围内的所有节点。每当有新条目进来的时候就更新这些索引变量的位置直到达到预设容量上限为止[^3]。 ```java // Java Example of a simple queue using an array with fixed capacity. public class SimpleQueue<T> { private T[] elements; private int head = 0; // Index for the front element private int tail = -1; // Index where next insertion will occur private final int CAPACITY; @SuppressWarnings("unchecked") public SimpleQueue(int cap){ this.CAPACITY = cap; this.elements = (T[]) new Object[CAPACITY]; } public boolean enqueue(T item){ /* ... */ } public T dequeue(){ /* ... */ } } ``` #### 优先队列高级特性支持下的实现方案 鉴于上述提到的功能需求,最常见也最为有效的做法就是基于二叉堆这一特定类型的完全二叉树模型之上建立起来。该种结构不仅能够很好地满足基本功能的要求,而且还能保证每次插入/删除操作的时间复杂度维持在一个较低水平上(O(log n))。因此非常适合用于那些需要频繁访问最大值或者最小值的应用场景之中[^1]。 ```c++ #include <vector> using namespace std; template<typename T> class PriorityQueue { private: vector<T> heap; protected: void upAdjust(); // Adjust upward after insertions void downAdjust(size_t pos); // Adjust downward during deletions public: bool isEmpty() const {return heap.empty();} void push(const T& value); T pop(); }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值