数据结构与算法——13.队列的拓展

news2025/1/11 15:48:21

这篇文章主要讲一下双端队列,优先队列,阻塞队列等队列的拓展内容。

目录

1.队列拓展概述

2.双端队列的链表实现

3.双端队列的数组实现

4.优先队列无序数组实现

5.阻塞队列

6.总结


1.队列拓展概述

首先来看一张图,来大致了解一下他们的区别。

双端队列:即两端都可以删除和添加的队列,并且满足队列FIFO的特点。

2.双端队列的链表实现

下面来看一下双端队列的链表实现:

代码如下:

/**
 * 基于双向环形链表实现双端队列
 * */
public class L15_LinkedListDeque<E> implements L15_TwoQueue<E> {

    /**节点类的设计*/
    static class Node<E>{
        Node<E> prev;
        E value;
        Node<E> next;
        /**节点的构造函数*/
        public Node(Node<E> prev,E value,Node<E> next){
            this.prev = prev;
            this.value = value;
            this.next = next;
        }
    }

    int capacity;//容量
    int size;//有效元素个数
    Node<E> sentinel = new Node<>(null,null,null);//创建一个节点(哨兵)

    /**双端队列的构造函数*/
    public L15_LinkedListDeque(int capacity) {//构建成环
        this.capacity = capacity;
        sentinel.next = sentinel;
        sentinel.prev = sentinel;
    }
    /**头部插入
     * 核心逻辑就是找插入节点的上一个和下一个节点
     * */
    @Override
    public boolean offerFirst(E e) {
        if (isFull())
            return false;
        Node<E> a = sentinel;
        Node<E> b = sentinel.next;
        Node<E> added = new Node<>(a,e,b);
        a.next = added;
        b.prev = added;
        size++;
        return true;
    }

    @Override
    public boolean offerLast(E e) {
        if (isFull())
            return false;
        Node<E> a = sentinel.prev;
        Node<E> b = sentinel;
        Node<E> added = new Node<>(a,e,b);
        a.next = added;
        b.prev = added;
        size++;
        return true;
    }

    @Override
    public E pollFirst() {
        if (isEmpty())
            return null;
        Node<E> a = sentinel;
        Node<E> removed = sentinel.next;
        Node<E> b = removed.next;
        a.next = b;
        b.prev = a;
        size--;
        return removed.value;
    }

    @Override
    public E pollLast() {
        if (isEmpty())
            return null;
        Node<E> removed = sentinel.prev;
        Node<E> a = removed.prev ;
        Node<E> b = sentinel;
        a.next = b;
        b.prev = a;
        size--;
        return removed.value;
    }

    @Override
    public E peekFirst() {
        if (isEmpty())
            return null;
        return sentinel.next.value;
    }

    @Override
    public E peekLast() {
        if (isEmpty())
            return null;
        return sentinel.prev.value;
    }

    @Override
    public boolean isEmpty() {
        return size == capacity;
    }

    @Override
    public boolean isFull() {
        return size == 0;
    }
}

3.双端队列的数组实现

下面看一下双端队列的数组实现:

下面看一下具体的代码:

/**用数组来实现双端队列*/
public class L15_ArrayDeque<E> implements L15_TwoQueue<E>{

    E[] array;
    int head;//头指针
    int tail;//尾指针

    /**构造函数,创建出数组(也就是双端队列)*/
    public L15_ArrayDeque(int capacity) {
        array = (E[]) new Object[capacity+1];
    }

    /**处理索引越界的两个方法*/
    /**处理索引加1时的*/
    static int inc(int i, int length){
        if (i+1 >= length){
            return 0;
        }
        return i+1;
    }
    /**处理索引减1时的*/
    static int dec(int i, int length){
        if (i-1 < 0){
            return length-1;
        }
        return i-1;
    }

    @Override
    public boolean offerFirst(E e) {
        if (isFull())
            return false;
        head = dec(head,array.length);
        array[head] = e;
        return true;
    }

    @Override
    public boolean offerLast(E e) {
        if (isFull())
            return false;
        array[tail] = e;
        tail = inc(tail,array.length);
        return true;
    }

    @Override
    public E pollFirst() {
        if (isEmpty())
            return null;
        E e = array[head];
        head = inc(head,array.length);
        return e;
    }

    @Override
    public E pollLast() {
        if (isEmpty())
            return null;
        tail = dec(tail,array.length);
        return array[tail];
    }

    @Override
    public E peekFirst() {
        return array[head];
    }

    @Override
    public E peekLast() {
        return array[tail];
    }

    @Override
    public boolean isEmpty() {
        return head == tail;
    }

    @Override
    public boolean isFull() {
        if (tail>head)
            return tail-head == array.length-1;
        if (tail<head)
            return head-tail == 1;
        if (tail == head)
            return false;
        return true;
    }
}

用数组实现双端队列不是太清楚,主要还是用链表来实现吧。

4.优先队列无序数组实现

优先队列,就是队列中的元素具有不同优先级的一种队列。入队的操作和普通队列一样,但是出队时是优先级高的元素先出队。

下面我们来看一下优先队列的具体实现:

下面看一下具体的代码:



/**
 * 用无序数组来实现优先队列
 * */
public class L16_PriorityQueue<E extends L16_Priority> implements L8_QueueInter<E>{

    L16_Priority[] array;
    int size;

    public L16_PriorityQueue(int capacity) {
        array = new L16_Priority[capacity];
    }


    @Override
    public boolean offer(E value) {
        if(isFull())
            return false;
        array[size] = value;
        size++;
        return true;
    }

    /**返回优先级最高的索引*/
    private int selectMax(){
        int max = 0;
        for (int i = 0; i < size; i++) {
            if (array[i].priority() > array[max].priority())
                max = i;
        }
        return max;
    }

    @Override
    public E poll() {
        if (isEmpty())
            return null;
        int max = selectMax();
        E e = (E)array[max];
        remove(max);
        return e;
    }

    private void remove(int index){
        if (index < size-1){
            System.arraycopy(array,index+1,array,index,size-1-index);
        }
        size--;
    }

    @Override
    public E peek() {
        if (isEmpty())
            return null;
        int max = selectMax();
        return (E)array[max];
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public boolean isFull() {
        return size == array.length;
    }
}

不算难,理清思路很简单的。

优先队列基于有序数组的实现和这个类似,并且比这个更简单,就是在入队操作时要找准位置而已。

5.阻塞队列

阻塞队列涉及的其他方面的内容,当我那部分的内容更新完毕后,再回来更新这个阻塞队列的实现。

6.总结

总的来说,队列不难,关键就是抓住链表和数组的特点,掌握链表和数组的相关操作就行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1030509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TorchLens--可视化任何PyTorch模型

0. 简介 PyTorch是一个深度学习框架&#xff0c;它使用张量&#xff08;tensor&#xff09;作为核心数据结构。在可视化PyTorch模型时&#xff0c;了解每个张量运算的意义非常重要。张量运算作为神经网络模型中的基本操作。它们用于处理输入数据、执行权重更新和生成预测结果。…

Python:获取当前目录下所有文件夹名称及文件夹下所有文件名称

获取当前目录下所有文件夹名称 def get_group_list(folder_path):group_list []for root, dirs, files in os.walk(folder_path):for dir in dirs:group_list.append(dir)return group_list获取文件夹下所有文件名称 def get_file_list(folder_path, group_name):file_list …

【zookeeper】基于Linux环境安装zookeeper集群

前提&#xff0c;需要有几台linux机器&#xff0c;我们可以准备好诸如finalshell来连接linux并且上传文件&#xff1b; 其次Linux需要安装上ssh&#xff0c;并且在/etc/hosts文件中写好其他几台机器的名字和Ip 127.0.0.1 localhost localhost.localdomain localhost4 localh…

canal简单介绍

简介 https://github.com/alibaba/canal 基于 MySQL 数据库增量日志解析&#xff0c;提供增量数据订阅和消费 原理是使用程序模拟一个mysql的从库&#xff0c;使主库发送同步日志给程序&#xff0c;程序再对数据进行处理&#xff0c;比如同步到其他数据库。 使用 下图是一个…

【计算机网络】图解路由器(一)

图解路由器&#xff08;一&#xff09; 1、什么是路由器&#xff1f;2、什么是路由选择&#xff1f;3、什么是转发&#xff1f;4、路由器设备有哪些类型&#xff1f;5、根据性能分类&#xff0c;路由器有哪些类型&#xff1f;5.1 高端路由器5.2 中端路由器5.3 低端路由器 6、什…

Dubbo面试题(三)

文章目录 前言一、Dubbo 的注册中心集群挂掉&#xff0c;发布者和订阅者之间还能通信么&#xff1f;二、Dubbo和Spring的关系三、Dubbo 使用的是什么通信框架?四、Dubbo 集群提供了哪些负载均衡策略&#xff1f;五、Dubbo 的集群容错方案有哪些&#xff1f;六、Dubbo 的默认集…

33.CSS发光按钮的悬停效果

特效 源码 indexhtml <!DOCTYPE html> <html> <head><title>CSS Modern Button</title><link rel="stylesheet" type="text/css" href="style.css"> </head> <body><a href="#"…

【数据结构练习】链表面试题集锦二

目录 前言&#xff1a; 1.链表分割 2.相交链表 3.环形链表 4.环形链表 II 前言&#xff1a; 数据结构想要学的好&#xff0c;刷题少不了&#xff0c;我们不仅要多刷题&#xff0c;还要刷好题&#xff01;为此我开启了一个必做好题锦集的系列&#xff0c;每篇大约5题左右。此…

大数据Flink(八十五):Window TVF 支持多维数据分析

文章目录 Window TVF 支持多维数据分析 一、Grouping Sets 二、​​​​​​​Rollup

学习记忆——宫殿篇——记忆宫殿——记忆桩——风景

河边街道窗框空间房顶楼房水塔山顶塔桥舟桥楼观景台 车顶架碧水池&#xff08;喷泉&#xff09;塔腰楼顶房檐碑石狮箱车叉牌摩托灯

Qt5开发及实例V2.0-第十二章-Qt多线程

Qt5开发及实例V2.0-第十二章-Qt多线程 第12章 Qt 5多线程12.1 多线程及简单实例12.2 多线程控制12.2.1 互斥量12.2.2 信号量12.2.3 线程等待与唤醒 12.3 多线程应用12.3.1 【实例】&#xff1a;服务器编程12.3.2 【实例】&#xff1a;客户端编程 本章相关例程源码下载1.Qt5开发…

Qt5开发及实例V2.0-第十三章-Qt数据库

Qt5开发及实例V2.0-第十三章-Qt数据库 第13章 Qt 5数据库13.1 数据库基本概念13.2 常用SQL命令13.2.1 数据查询13.2.2 数据操作 13.3 Qt操作数据库及实例13.3.1 Qt操作SQLite数据库13.3.2 Qt操作主/从视图及XML 本章相关例程源码下载1.Qt5开发及实例_CH1301.rar 下载2.Qt5开发及…

GLTF编辑器:在线模型材质编辑工具

GLTF 编辑器 是一个功能强大、易于使用的在线3D模型编辑和查看工具&#xff0c;它支持多种格式的3D模型导入并将模型导出为GLB格式&#xff0c;除了可以对3D模型进行基本属性的修改之外&#xff0c;还支持对模型原点重置以及模型材质纹理修改。对于3D开发者和设计师来说&#x…

基于FPGA的图像白平衡算法实现,包括tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 vivado2019.2 matlab2022a 3.部分核心程序 timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 202…

数据治理-EDRM电子取证

EDRM是电子取证标准和指南的组织,该框架提供了一种电子取证的方法,对于涉及确定相关内部数据的存储方式和位置、适用什么保留策略、哪些数据不可访问以及哪些工具可用于协助识别流程的人员来说,这种方法非常方便。 EDRM模型假定数据或信息治理已到位。该模型包括8个…

20230918使用ffmpeg将mka的音频转为AAC编码以便PR2023来识别

20230918使用ffmpeg将mka的音频转为AAC编码以便PR2023来识别 2023/9/18 20:58 ffmpeg -i 1.mka -acodec aac 1.mp4 ffmpeg -i 1.mka -vn -c:a aac 2.aac ffmpeg -i 1.mka -vn -c:a aac 2.MP4 ffmpeg mka 转 aacmp4 https://avmedia.0voice.com/?id42526 用ffmpeg将mka格式转化…

flink集群与资源@k8s源码分析-flink kubeclient

flink kubeclient是面向flink应用的fabric8 kubeclient的封装,本文分析flink如何封装kubeclient,核心组件是装饰器,资源和ServiceType,下面通过分析业务创建作业管理器组件(createJobManagerComponent)了解flink kubeclient 1 场景 2 新建作业管理器组件 1. KubernetesJob…

【Java 基础篇】Java同步方法解决数据安全

多线程编程是现代应用程序开发中的常见需求&#xff0c;它可以提高程序的性能和响应能力。然而&#xff0c;多线程编程也带来了一个严重的问题&#xff1a;数据安全。在多线程环境下&#xff0c;多个线程同时访问和修改共享的数据可能导致数据不一致或损坏。为了解决这个问题&a…

一次ES检索的性能优化经验记录

优化功能: 统一检索能力&#xff0c;为各服务所调用。 该接口并发压力大&#xff0c;压测效果不理想。 初步2k线程两台压测机预发环境压测结果两pod下为400qps左右&#xff0c;单pod 平均qps200&#xff0c;响应时间在五分钟之后达到了峰值&#xff0c;平响达到几十秒开外。 压…

万里牛与金蝶云星空对接集成查询调拨单连通调拨单新增(万里牛调拨单-金蝶【直接调拨单】)

万里牛与金蝶云星空对接集成查询调拨单连通调拨单新增(万里牛调拨单-金蝶【直接调拨单】) 源系统:万里牛 万里牛是杭州湖畔网络技术有限公司旗下SaaS软件品牌&#xff0c;主要针对电商、外贸、实体门店等业务群体&#xff0c;帮助企业快速布局新零售&#xff0c;提升订单处理效…