队列知识总结

tech2025-10-26  5

栈(Stack)和队列(Queue)的相同点和不同点是什么?如何用两个栈实现队列(入队和出队)?

相同点:

栈和队列都属于线性表栈和队列插入操作都是限定在线性表的头尾进行栈和队列插入和删除的时间复杂度是O(1)

不同点:

特性不同,栈先进后出 (LIFO,Last In First Out) ;队列先进先出 (FIFO,First In First Out)栈知识表的一端进行插入和删除操作,队列是在表的一端插入,另一端删除Java的栈(Stack)继承自 Vector,再往上的接口是 List/Collection;队列(Queue)直接继承自Collection接口

栈实现队列:

/** * 两个栈组成队列 */ public class StackQueue<E> { //入队操作的栈 private Stack<E> stack1 =new Stack<>(); //出队操作的栈 private Stack<E> stack2 =new Stack<>(); /** * 压入队列元素,只使用stack1 * @param element */ public void push(E element) { stack1.add(element); } /** * 取出队列顶部元素 * @return */ public E poll() { // stack2的数据为空时,才把stack1中的元素压入stack2(两种情况:1、初始化时两个栈的数据均为空;2、stack2数据出栈出完了 if (stack2.isEmpty()) { while (stack1.size() > 0) { stack2.add(stack1.pop()); } } //stack1的数据出栈完成后,stack2仍然为空,说明两个栈的数据都为空 if (stack2.isEmpty()) { throw new RuntimeException("queue is Empty!"); } E head = stack2.pop(); return head; } }

队列实现栈:

class MyStack { Queue<Integer> queue; /** Initialize your data structure here. */ public MyStack() { queue = new LinkedList<>(); } /** Push element x onto stack. */ public void push(int x) { queue.add(x); for (int i = 1; i < queue.size(); i++) { queue.add(queue.remove()); } } /** Removes the element on top of the stack and returns that element. */ public int pop() { return queue.poll(); } /** Get the top element. */ public int top() { return queue.peek(); } /** Returns whether the stack is empty. */ public boolean empty() { return queue.size() == 0; } }

栈和队列都属于线性表(linear list),而线性表是 n 个具有相同特性的数据元素的有限序列

Queue及常用子类可分三类:

双端队列(Deque):头部和尾部都支持插入和获取阻塞队列(BlockingQueue):在元素的添加/删除操作时,如果没有成功,会阻塞等待执行。例如:当添加元素时,如果队列元素已满,队列会阻塞等待直到有空位时再插入非阻塞队列(Non BlockingQueue):在元素的添加/删除操作时,如果没有成功,会直接返回操作的结果(通常双端队列也属于非阻塞队列)常见的Queue的特性: PriorityBlockingQueue:带优先级的无界阻塞队列,元素按优先级顺序被移除,而不是先进先出队列(FIFO)。此外,队列中的元素要具有比较能力(用于判定优先级)。PriorityBlockingQueue 不允许 null 元素DelayQueue:存放 Delayed 元素的无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,DelayQueue 不允许使用 null 元素SynchronousQueue:同步阻塞队列,它的每个插入操作都要等待其他线程相应的移除操作,反之亦然。它的一个典型应用场景是 Executors.newCachedThreadPool () ,在新任务到来时创建新的线程,如果有空闲线程则会重复使用,SynchronousQueue 不允许 null 元素

LinkedHashMap和PriorityQueue的区别?

PriorityQueue 是一个优先级队列,保证最高或者最低优先级的的元素总是在队列头部,但是 LinkedHashMap 维持的顺序是元素插入的顺序。当遍历一个 PriorityQueue 时,没有任何顺序保证,但是 LinkedHashMap 课保证遍历顺序是元素插入的顺序

Queue中add/offer方法的区别?

add()和offer()都是向队列中添加一个元素。一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,调用 add() 方法就会抛出IllegalStateException异常,而调用 offer() 方法会返回 false

Queue中remove()/poll()方法的区别?

poll()/remove()方法都是从队列中删除头部元素。如果队列元素为空,调用remove() 则会抛出NoSuchElementException,而poll() 方法在用空集合调用时只是返回 null。

Queue中element()/peek()方法的区别?

element() 和 peek() 用于在队列的头部查询元素。与 remove() 方法类似,在队列为空时, element() 抛出NoSuchElementException异常,而 peek() 返回 null

BlockingQueue有哪些实现类?ArrayBlockingQueue: 由数组组成的有界阻塞队列?

LinkedBlockingQueue: 由链表组成的有界阻塞队列(默认大小为 Integer.MAX_VALUE)PriorityBlockingQueue:支持优先级排序的无界阻塞队列DelayQueue:使用优先级队列实现的延迟无界阻塞队列SynchronousQueue: 不存储元素的阻塞队列,单个元素的队列,同步提交队列LinkedTransferQueue:链表组成的无界阻塞队列LinkedBlockingDeque:链表组成的双向阻塞队列

文章推荐:

无锁队列:无锁队列总结线性结构系列: 线性表 及Java实现 顺序表、链表、栈、队列
最新回复(0)