队列(Queue)与双端队列 (Deque)

Posted Mᴇᴇᴛ ꦿ᭄.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了队列(Queue)与双端队列 (Deque)相关的知识,希望对你有一定的参考价值。

目录

1.队列(Queue)

1.1 概念

1.2 队列的使用 

1.3 队列模拟实现

 1.4 循环队列

 2. 双端队列 (Deque)


1.队列(Queue)

1.1 概念

队列 :只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列:进行插入操作的一端称为 队尾( Tail/Rear 出队列:进行删除操作的一端称为 队头 Head/Front

1.2 队列的使用 

Java中,Queue是个接口,底层是通过链表实现的。

 

注意:Queue是个接口,在实例化时必须实例化LinkedList的对象,因为LinkedList实现了Queue接口。

 

public static void main(String[] args) 
    Queue<Integer> q = new LinkedList<>();
    q.offer(1);
    q.offer(2);
    q.offer(3);
    q.offer(4);
    q.offer(5); // 从队尾入队列
    System.out.println(q.size());
    System.out.println(q.peek()); // 获取队头元素
    q.poll();
    System.out.println(q.poll()); // 从队头出队列,并将删除的元素返回
    if(q.isEmpty())
        System.out.println("队列空");
    else
        System.out.println(q.size());
    

1.3 队列模拟实现

队列中既然可以存储元素,那底层肯定要有能够保存元素的空间,通过前面线性表的学习了解到常见的空间类型有两种:顺序结构 和 链式结构

public class Queue 
    // 双向链表节点
    public static class ListNode
        ListNode next;
        ListNode prev;
        int value;
        ListNode(int value)
            this.value = value;
        
    
    ListNode first; // 队头
    ListNode last; // 队尾
    int size = 0;
    // 入队列---向双向链表位置插入新节点
    public void offer(int e)
        ListNode newNode = new ListNode(e);
        if(first == null)
            first = newNode;
            // last = newNode;
        else
            last.next = newNode;
            newNode.prev = last;
            // last = newNode;
        
        last = newNode;
        size++;
    
    // 出队列---将双向链表第一个节点删除掉
    public int poll()
        // 1. 队列为空
        // 2. 队列中只有一个元素----链表中只有一个节点---直接删除
        // 3. 队列中有多个元素---链表中有多个节点----将第一个节点删除
        int value = 0;
        if(first == null)
            return null;
        else if(first == last)
            last = null;
            first = null;
        else
            value = first.value;
            first = first.next;
            first.prev.next = null;
            first.prev = null;
        
        --size;
        return value;
    
    // 获取队头元素---获取链表中第一个节点的值域
    public int peek()
        if(first == null)
            return null;
        
        return first.value;
    
    public int size() 
        return size;
    
    public boolean isEmpty()
        return first == null;
    

 1.4 循环队列

实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型时可以就会使用循环队列。环形队列通常使用数组实现。

 

数组下标循环的小技巧         1. 下标最后再往后 (offffset 小于 array.length): index = (index + offffset) % array.length

        2. 下标最前再往前(offffset 小于 array.length): index = (index + array.length - offffset) % array.length 

如何区分空与满

1. 通过添加 size 属性记录 2. 保留一个位置 3. 使用标记

 2. 双端队列 (Deque)

 

双端队列( deque )是指允许两端都可以进行入队和出队操作的队列, deque “double ended queue” 的简称。那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。

Deque是一个接口,使用时必须创建LinkedList的对象。 

 

在实际工程中,使用Deque接口是比较多的,栈和队列均可以使用该接口。

Deque<Integer> stack = new ArrayDeque<>();// 双端队列的线性实现 Deque<Integer> queue = new LinkedList<>();// 双端队列的链式实现

C++ stl queue(单端队列)和stl deque(双端队列)的区别(与循环队列的区别)

参考文章1:c++基础之queue和deque比较

参考文章2:C++ queue 和 deque的区别

参考文章3:C++ STL deque容器(详解版)

文章目录

queue示例

#include <queue>
#include <iostream>
using namespace std;


int main() 

	queue<int> q;

	//cout << "队头元素为:" << q.front() << endl;	//运行报错,队列必须先判空,下同
	//cout << "队尾元素为:" << q.back() << endl;

	for (int i = 0; i < 10; i++) 
	
		q.push(i);
	

	if (!q.empty()) 
	
		cout << "队列q非空!" << endl;
		cout << "q中有" << q.size() << "个元素" << endl;

		cout << "队头元素为:" << q.front() << endl;
		cout << "队尾元素为:" << q.back() << endl;

		int size = q.size();
		for (int j = 0; j < size; j++)
		
			cout << q.front() << " ";
			q.pop();
		
		cout << endl;
	

	if (!q.empty()) 
	
		cout << "队列非空!" << endl;
	
	else
	
		cout << "队列为空!" << endl;
	

	system("pause");
	return 0;

参考文章:C++队列(queue、deque)

deque示例

参考文章3:C++ STL deque容器(详解版)

循环队列?

老看有人自行实现循环队列,但直接用stl queue不就行了,还用自行实现循环队列吗?我有点懵逼

看到篇文章说std::deque被相当仔细地定义为线性队列。它的设计并不真正适合循环队列,不知是真是假

参考文章:c++ - 使用 STL 队列的循环队列?

以上是关于队列(Queue)与双端队列 (Deque)的主要内容,如果未能解决你的问题,请参考以下文章

LinkedBlockingQueue

C++ stl queue(单端队列)和stl deque(双端队列)的区别(与循环队列的区别)

C++ stl queue(单端队列)和stl deque(双端队列)的区别(与循环队列的区别)

C++初阶----deque(双端队列)+stack queue模拟实现

6-5-2:STL之stack和queue——双端队列deque

集合类