数据结构-循环队列和循环双端队列的多角度实现

文章目录

      • 1. 循环队列的数组形式实现
      • 2. 循环队列的链表实现
      • 3. 循环双端队列的数组形式实现
      • 4. 循环双端队列的链表实现

在力扣的题面如下
在这里插入图片描述
在这里插入图片描述

1. 循环队列的数组形式实现

其实循环队列的数组形式只有下面要注意的点,只要掌握了下面的这几点,代码层面上就没有什么问题了

用数组模拟的思路跟循环单向队列是完全一致的,要记住下面的几个点

  • 1 . first 指向的是头元素的下标 , last 指向的是尾元素的下一个位置的下标
  • 2 . 在申请数组空间的时候要多申请一个空间的目的是,讲判断空与判断满的条件区分开
  • 判断空就是 first == last 判断满就是 "first的下一个" == last;
    
  • 3 . 在循环队列里面,如何++,如何–?
  • ++ : (first + 1) % len  ;  (last + 1) % len;
    
  • -- : (first - 1 + len) % len  ;  (last - 1 + len) % len
    
  • 4 . 元素的个数 size == (last - fist + len) % len;

下面是数组形式的实现代码

class MyCircularQueue {
    int[] elementData;
    int first;
    int last;

    public MyCircularQueue(int k) {
        elementData = new int[k + 1];
    }
    
    public boolean enQueue(int value) {
        if(isFull()){
            return false;
        }
        elementData[last] = value;
        last = (last + 1)%  elementData.length;
        return true;
    }
    
    public boolean deQueue() {
         if(isEmpty()){
             return false;
         }
         first = (first + 1)%elementData.length;
         return true;
    }
    
    public int Front() {
         if(isEmpty()){
             return -1;
         }
         return elementData[first];
    }
    
    public int Rear() {
         if(isEmpty()){
             return  -1;
         }
         int index = last == 0 ? elementData.length - 1 : last -1;
         return elementData[index];
    }
    
    public boolean isEmpty() {
        return last == first;
    }
    
    public boolean isFull() {
         return first == (last + 1)  % elementData.length;
    }
}

/**
 * Your MyCircularQueue object will be instantiated and called as such:
 * MyCircularQueue obj = new MyCircularQueue(k);
 * boolean param_1 = obj.enQueue(value);
 * boolean param_2 = obj.deQueue();
 * int param_3 = obj.Front();
 * int param_4 = obj.Rear();
 * boolean param_5 = obj.isEmpty();
 * boolean param_6 = obj.isFull();
 */

2. 循环队列的链表实现

鉴于单链表的尾巴节点每次都要寻找,所以为了简便,我们采用双向链表进行模拟,注意,这里我们对于链表节点的定义就是我们LinkedList中的源码形式,有空可以去看看我们LinkedList的底层源码,这里其实就是多了个size来标记我们的链表节点数量
代码实现如下


/**
 * 尝试用双向链表来模拟循环队列
 */
public class CircleQueue {


    /**
     * 下面是根据原代码模拟的定义的节点类
     * @param <T>
     */
    static class Node<T> {
        public T item;
        public Node<T> prev;
        public Node<T> next;

        public Node (Node<T> prev,T item,Node<T> next) {
            this.prev = prev;
            this.item = item;
            this.next = next;
        }
    }

    /**
     * 下面是所需要的基本结构
     */
    private Node first;
    private Node last;
    private int size;
    private int capacity;


    public CircleQueue(int k) {
        this.size = 0;
        first = last = null;
        capacity = k;
    }

    public boolean enQueue(int value) {
        if(isFull()){
            return false;
        }

        Node<Integer> node = new Node<>(null,value,null);
        if(first == null && last == null){
            first = node;
            last = node;
        }else{
            last.next = node;
            node.prev = last;
            last = node;
        }
        this.size++;
        return true;
    }

    public boolean deQueue() {
        if(isEmpty()){
            return false;
        }

        if(last == first){
            last = first = null;
        }else{
            first = first.next;
            first.prev.next = null;
            first.prev.item = null;
        }
        this.size--;
        return true;
    }

    public int Front() {
        if(isEmpty()){
            return -1;
        }
        return (int)first.item;
    }

    public int Rear() {
        if(isEmpty()){
            return -1;
        }

        return (int)last.item;
    }

    public boolean isEmpty() {
        return first == null && last == null;
    }

    public boolean isFull() {
        return this.size == this.capacity;
    }
}

3. 循环双端队列的数组形式实现

用数组实现队列源码层面是我们的ArrayDeque这个类完成的,这里不再多说了,和我们的1.用数组实现循环队列是一致的

/**
 * 首先尝试是数组来模拟循环双端队列
 * 其次我们再用双向链表来尝试模拟一下循环双端队列
 * 用数组模拟的思路跟循环单向队列是完全一致的,要记住下面的几个点
 * 1 . first 指向的是头元素的下标 , last 指向的是尾元素的下一个位置的下标
 * 2 . 在申请数组空间的时候要多申请一个空间的目的是,讲判断空与判断满的条件区分开
 *     判断空就是 first == last 判断满就是 "first的下一个" == last;
 * 3 . 在循环队列里面,如何++,如何--?
 *     ++ : (first + 1) % len  ;  (last + 1) % len;
 *     -- : (first - 1 + len) % len  ;  (last - 1 + len) % len
 * 4 . size == (last - fist + len) % len;
 */
class MyCircularDeque {

    int[] elementData;
    int first;
    int last;

    public MyCircularDeque(int k) {
        elementData = new int[k + 1];
        first = last = 0;
    }

    public boolean insertFront(int value) {
        if(isFull()){
            return false;
        }

        first = (first - 1 + elementData.length) % elementData.length;
        elementData[first] = value;
        return true;
    }

    public boolean insertLast(int value) {
        if(isFull()){
            return false;
        }

        elementData[last] = value;
        last = (last + 1) % elementData.length;
        return true;
    }

    public boolean deleteFront() {
        if(isEmpty()){
            return false;
        }

        first = (first + 1) % elementData.length;
        return true;
    }

    public boolean deleteLast() {
        if(isEmpty()){
            return false;
        }

        last = (last - 1 + elementData.length) % elementData.length;
        return true;
    }

    public int getFront() {
        if(isEmpty()){
            return -1;
        }

        return elementData[first];
    }

    public int getRear() {
        if(isEmpty()){
            return -1;
        }

        return elementData[(last - 1 + elementData.length) % elementData.length];
    }

    public boolean isEmpty() {
        return first == last;
    }

    public boolean isFull() {
        return (last + 1) % elementData.length == first;
    }
}

4. 循环双端队列的链表实现

其实就是比2.多了一个addFirst,和 removeLast
代码实现如下


/**
 * 下面我们尝试使用双向链表来模拟我们的循环双端队列
 */
class MyCircularDequeUseLinkedList {
    static class Node<T> {
        Node<T> prev;
        T item;
        Node<T> next;

        public Node(Node<T> prev,T item,Node<T> next){
            this.prev = prev;
            this.item = item;
            this.next = next;
        }
    }
    private int size;
    private int capacity;
    private Node first;
    private Node last;

    public MyCircularDequeUseLinkedList(int k) {
        this.size = 0;
        last = first = null;
        this.capacity = k;
    }

    public boolean insertFront(int value) {
        if(isFull()){
            return false;
        }

        Node<Integer> node = new Node<>(null,value,null);
        if(isEmpty()){
            first = last = node;
        }else{
            node.next = first;
            first.prev = node;
            first = node;
        }
        size++;
        return true;
    }

    public boolean insertLast(int value) {
        if(isFull()){
            return false;
        }

        Node<Integer> node = new Node<>(null,value,null);
        if(isEmpty()){
            first = last = node;
        }else{
            last.next = node;
            node.prev = last;
            last = node;
        }
        size++;
        return true;
    }

    public boolean deleteFront() {
        if(isEmpty()){
            return false;
        }

        if(first == last){
            last = first = null;
        }else{
            first = first.next;
            first.prev.next = null;
            first.prev.item = null;
            first.prev = null;
        }
        size--;
        return true;
    }

    public boolean deleteLast() {
        if(isEmpty()){
            return false;
        }

        if(last == first){
            first = last = null;
        }else{
            last = last.prev;
            last.next.prev = null;
            last.next.item = null;
            last.next = null;
        }
        size--;
        return true;
    }

    public int getFront() {
        if(isEmpty()){
            return -1;
        }
        return (int)first.item;
    }

    public int getRear() {
        if(isEmpty()){
            return -1;
        }
        return (int)last.item;
    }

    public boolean isEmpty() {
        return first == null && last == null;
    }

    public boolean isFull() {
        return this.size == this.capacity;
    }
}

为什么不用单链表实现的原因其实是单链表每次想尾插都要走到最后一个位置,时间复杂度太高,有兴趣的话也可以自己模拟一下试试

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

了解 Unity AI:从初学者到高级的综合指南

游戏中的AI是什么? 游戏中的人工智能是指利用人工智能技术使视频游戏中的非玩家角色和实体智能地行动、做出决策、对游戏环境做出反应,并提供引人入胜的动态游戏体验。什么是NPC? NPC 代表“非玩家角色”。NPC 是视频游戏、角色扮演游戏中不受人类玩家控制的角色。它们是计算…

Git 新手快速入门教程

一、什么是 Git 1. 何为版本控制 版本控制是一种记录文件变化的系统&#xff0c;可以跟踪文件的修改历史&#xff0c;并允许用户在不同版本之间进行比较、恢复或合并。它主要用于软件开发过程中管理代码的变更&#xff0c;但也可以应用于任何需要跟踪文件变更的场景。 版本控…

【学习笔记二十一】EWM仓库两步拣配配置及操作展示

一、EWM两步拣配配置 1.定义两步拣配的WPT ①第一步:标准WPT2020,目标仓位是2010两步拣配的仓位,并创建存储类型2010的两步拣配的仓位 ②第二步,标准WPT2010,目标仓位9020发货区和发货的仓位 2.定义确定仓库处理类型的控制标识 3.确定仓库处理类型 4.仓库编码级别需要允…

路由引入、路由策略、路由过滤实验

实验拓扑 实验思路 配置ip地址&#xff0c;配置RIP,OSPF;在R2上分别在RIP下引入OSPF&#xff0c;在OSPF下引入RIP;在R2上配置acl 2000,拒绝R4的业务网段&#xff0c;同时允许其他网段访问&#xff08;acl 2000 默认拒绝网段&#xff09;&#xff1b;通过配置路由过滤router-…

数据分析_数据分析思维(1)

数据分析_数据分析思维(1) 这篇文章具体的给大家介绍数据分析中最为核心的技术之一: 数据分析思维的相关内容。 一、数据分析的三种核心思维 作为新手数据分析师或数据运营, 在面对数据异常的时候, 好多小伙伴都会出现: “好像是A引起的”, “好像也和B渠道有关”, “也可能…

OpenCV与AI深度学习 | OpenCV如何读取仪表中的指针刻度

本文来源公众号“OpenCV与AI深度学习”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;OpenCV如何读取仪表中的指针刻度 最近遇到一个问题&#xff0c;如何读取仪表中的指针指向的刻度。 解决方法有多种&#xff0c;比如&#xff…

队列常规使用

文章目录 一、同步互斥改进方法二、队列实现同步三、队列实现互斥总结 一、同步互斥改进方法 在上一章同步互斥中&#xff0c;我们有两个实验。 同步实验&#xff1a; 我们创建了两个任务&#xff0c;任务1循环遍历一个比较大的数字&#xff0c;遍历完成后设置标志位置1。任务…

如何用网页绘制一个黑莓9900的键盘效果图

如何用网页绘制一个黑莓9900的键盘效果图 入了几个黑莓蓝牙键盘&#xff0c;出于喜好&#xff0c;想做一个跟实体键盘一模一样的网页界面。 最终的实现效果是这样的&#xff1a; 在线查看&#xff1a;http://kylebing.cn/tools/bb-keyboard 点击上面四个按键显示不同模型界面…

PDM在Office文档中的变量映射

在PDM数据管理软件中需要在数据卡中反馈出文件的一些属性信息&#xff0c;使得用户在不打开文件的情况下可以快速了解此文件的属性信息&#xff0c;或者需要用户在创建文档时填入相应内容&#xff0c;能够自动的填充到文档中&#xff0c;所以就需要在实施的过程中在SOLIDWORKS …

[C++][算法基础]求组合数(I)

给定 &#x1d45b; 组询问&#xff0c;每组询问给定两个整数 &#x1d44e;&#xff0c;&#x1d44f;&#xff0c;请你输出 的值。 输入格式 第一行包含整数 &#x1d45b;。 接下来 &#x1d45b; 行&#xff0c;每行包含一组 &#x1d44e; 和 &#x1d44f;。 输出格…

CSS布局 Flex 和 Grid

在 CSS 中&#xff0c;理解 flex 和 Grid 布局非常重要&#xff0c;今天把这两个重要知识点回顾一下。 Flexbox 弹性盒子布局 弹性布局支持 flex、inline-flex&#xff0c;支持块和内联。 容器 轴的概念&#xff0c;在 Flexbox&#xff0c;有主轴和侧轴的概念&#xff0c;轴…

自己写的加密案例4——某东方课程头部sign加密

网址&#xff1a;aHR0cHM6Ly9kc2FwaS54ZGYuY24vcHJvZHVjdC92Mi9jbGFzcy9zZWFyY2g 进行抓包分析&#xff0c;发现请求头中由sign加密&#xff0c;简单判断是消息摘要算法。 Sign:d7c68100ca508bb7c8ae284560754303 进行xhr断点&#xff0c;一下子就发现了位置。 s c.sign&…

“傻瓜”学计量——核密度估计KDE

提纲&#xff1a; 什么是核密度估计&#xff0c;是干什么的 代码 1 前言 参数估计vs非参数估计参数估计是样本数据来自一个具有明确概率密度函数的总体。非参数估计是样本数据的概率分布未知&#xff0c;这时&#xff0c;为了对样本数据进行建模&#xff0c;需要估计样本数据…

嵌入式面试-回答UART

说明&#xff1a; 此文章是在阅读了一些列面试相关资料之后对于一些常见问题的整理&#xff0c;主要针对的是嵌入式软件面试中涉及到的问答&#xff0c;努力精准的抓住重点进行描述。若有不足非常欢迎指出&#xff0c;感谢&#xff01;在总结过程中有些答案没标记参考来源&…

leetcode每日一题第五十六天

今天心情不好&#xff0c;就做一道 class Solution { public:int countTarget(vector<int>& scores, int target) {return help(scores,target)-help(scores,target-1);}int help(vector<int>&scores,int target){int left 0;int right scores.size()-1;…

针对窗口数量多导致窗口大小显示受限制的问题,使用滚动条控制窗口

建议&#xff1a;首先观察结果展示&#xff0c;判断是否可以满足你的需求。 目录 1. 问题分析 2. 解决方案 2.1 界面设计 2.2 生成代码 2.3 源码实现 3. 结果展示 1. 问题分析 项目需要显示的窗口数量颇多&#xff0c;主界面中&#xff0c;如果一次性显示全部窗口&#x…

Spring AOP (一)

本篇主要介绍Spring AOP的基础概念和入门使用 一、AOP的基本概念 AOP是一种面向切面编程的思想&#xff0c;它与IOC并称为Spring 的两大核心思想。什么是面向切面编程呢&#xff0c;具体来说就是对一类事情进行集中统一处理。这听起来像不像前面篇章中所介绍的统一功能处理&am…

❤️新版Linux零基础快速入门到精通——第三部分❤️

❤️新版Linux零基础快速入门到精通——第三部分❤️ 非科班的我&#xff01;Ta&#xff01;还是来了~~~3. Linux权限管控3.1 认知root用户3.1.1 Switch User——su3.1.2 sudo命令3.1.3 为普通用户配置sudo认证 3.2 用户和用户组3.2.1 用户、用户组3.2.2 用户组管理3.2.3 用户管…

YOLOv8-PySide --- 基于 ultralytics 8.1.0 发行版优化 | 代码已开源

YOLOv8-PySide — 基于 ultralytics 8.1.0 发行版优化 Github 项目地址&#xff1a;https://github.com/WangQvQ/Ultralytics-PySide6 BiliBili视频地址&#xff1a;https://www.bilibili.com/video 页面效果 如何使用 pip install ultralytics8.1.0 or git clone --branch v…

mysql基础3——创建和修改数据表

创建数据表 创建一个表&#xff08;importtype有默认值1&#xff09;并插入一条数据&#xff08;importtype字段没有指定值&#xff09; 约束 默认约束&#xff08;把设置的默认值自动赋值给字段&#xff09; create table demo.importhead(listnum int,supplied int,stock…