首页 > 编程语言 >yocto-queue 库如何实现替代数组【玩转源码】

yocto-queue 库如何实现替代数组【玩转源码】

时间:2023-12-03 19:32:24浏览次数:35  
标签:yocto head .# 队列 current Queue queue 源码

前言

前面提到了可以使用yocto-queue库代替Array操作数组,本篇则深入源码了解一下yocto-queue是如何实现替代数组的。

yocto-queue源码分析

源码中的代码量相对较少,读起来会比较轻松,看似可以琢磨的点少,其实不然。

代码中包含知识点主要包括类的属性链表与数组的对比队列、自定义迭代器等,容我细讲。

git 地址:yocto-queue

Node 类

node 类的作用是在新增操作中储存需要插入到队列中的元素。

class Node {
  value;
  next;

  constructor(value) {
    this.value = value;
  }
}

它有两个公有属性:

value:插入到队列中的元素。

next:下一个 Node 实例。

属性的两种写法

Node 类里面正好包含了这两种写法:

第一种,定义在 constructor() 方法里面的 this 上面;

第二种,定义在类的最顶层。(ES2022 新加的写法)

Queue 类

私有属性的“演化”

class Queue {
  #head;
  #tail;
  #size;
}

Queue 类里共包含三个私有属性:

#head:队列的头。

#tail:队列的尾。

#size:队列的长度。

在属性前面使用#,是 ES2022 新加入的写法,从此 class 正式有了私有属性。这个私有属性在 Queue 的外部是无法被使用的。

const queue = new Queue();
console.log(queue.#size);

外部使用 #size 属性,会抛出错误:

Private field '#size' must be declared in an enclosing class

在这之前主要采用命名方式的不同区分私有属性和公有属性。比如声明一个只有 Queue 内部可用使用的常量_limit。

_limit = 10;

但是其实 Queue 的实例是可以访问到的。

const queue = new Queue();
console.log(queue._limit); // 10

还有将私有方法的名字命名为一个 Symbol 值的方式,可以阅读阮一峰大佬的书详细了解。

链表 vs 数组

数组:一种有序线性数据结构,用一串连续的内存空间进行数据存储。

链表:一种无序线性数据结构,用一串非连续的内存空间进行数据存储,通过链表中节点的指针次序维护线性链路。

两个数据类型在操作元素时的时间复杂度的区别如下:

时间复杂度

数组

链表

添加

O (n)

O (1)

删除

O (n)

O (1)

读取

O (1)

O (n)

队列

yocto-queue 库提供的主要功能就是用链表实现队列,然后进行数据的添加和删除。

队列是具有先进先出 (FIFO) 原则的有序集合。

enqueue 入队列

该方法会从队列中的队尾添加一个元素。

class Queue {
  enqueue(value) {
    const node = new Node(value);

    if (this.#head) {
      this.#tail.next = node;
      this.#tail = node;
    } else {
      this.#head = node;
      this.#tail = node;
    }

    this.#size++;
  }
}

通过队头 #head 的值判断,需要插入的元素存放在队列中的位置:

如果 #head 的值存在,则新添加的元素放在队尾;

如果 #head 的值不存在,则新添加的元素即为队列的队头;

且队列长度加一。

dequeue 出队列

该方法会从队列中的队头元素移除,并返回移除的元素。

class Queue {
  dequeue() {
    const current = this.#head;
    if (!current) {
      return;
    }

    this.#head = this.#head.next;
    this.#size--;
    return current.value;
  }
}

先定义 current 指向队头的元素,通过 current 值的判断进行下一步操作:

如果 current 不存在,则表示队列中已经没有数据。

如果 current 存在,则将队头的元素移除,再队列的长度减一,并返回移除的元素。

我们来调用 dequeue 方法之后,查看队列的值:

const queue = new Queue();
queue.enqueue(3);
queue.enqueue(4);
queue.enqueue(5);
console.log(...queue); // 4 5

从打印结果可以看出元素3已经被移除。


自定义迭代器

数组拥有默认的迭代器行为,Queue 类的实例对象理论也应该拥有迭代器行为。

使用 Symbol.iterator 可以创建自定义迭代器创建方法很简单。

class Queue {
  *[Symbol.iterator]() {
    let current = this.#head;

    while (current) {
      yield current.value;
      current = current.next;
    }
  }
}

Queue 类定义的迭代器,从队列的头开始循环,把每一个元素都返回出来。

这样在查看队列数据的时候可以使用...展开:

const queue = new Queue();
queue.enqueue(3);
queue.enqueue(4);
queue.enqueue(5);
console.log(...queue); // 3 4 5

源码阅读的两个重要点

源码阅读的过程中,对实现方法和设计模式的分析、学习、吃透很重要。

遇到问题,提出疑问,寻找答案,这个过程同样重要。在这个过程里,除了锻炼了个人思考的能力,还可以帮助自信心的塑造

不要担心自己提的问题是多余的或者过于基础,由浅入深,在这个过程中可以实现经验的积累。而后,无论是看待问题的角度,还是提问的内容,都会变得精准。

总结

yocto-queue 库的源码阅读分析之后,收获如下:

  1. 通过对 yocto-queue 库的源码分析,了解了它如何替代数组以及若干知识点回顾。
  2. 额外的收获,关于源码阅读的两个重要点学习个人思考

作者:非职业「传道授业解惑」的开发者叶一一简介:「趣学前端」、「CSS畅想」系列作者,华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。如果看完文章有所收获,欢迎点赞

标签:yocto,head,.#,队列,current,Queue,queue,源码
From: https://blog.51cto.com/u_15838863/8668848

相关文章

  • Netty源码学习7——netty是如何发送数据的
    零丶引入系列文章目录和关于我经过《Netty源码学习4——服务端是处理新连接的&netty的reactor模式和《Netty源码学习5——服务端是如何读取数据的》,我们了解了netty服务端是如何建立连接,读取客户端数据的,通过《Netty源码学习6——netty编码解码器&粘包半包问题的解决》我们认识......
  • Java智慧工地一体化解决方案(里程碑管理)源码
    智慧工地为管理人员提供及时、高效、优质的远程管理服务,提升安全管理水平,确保施工安全提高施工质量。实现对人、机、料、法、环的全方位实时监控,变被动“监督”为主动“监控”。一、建设背景施工现场有数量多、分布广,总部统一管理难度大;工地作业流程节点多,缺少过程可视化管理,成本......
  • linux中make编译源码包失败
    报错如下,gcc版本太低^server.c:5346:31:错误:‘structredisServer’没有名为‘server_cpulist’的成员redisSetCpuAffinity(server.server_cpulist);^server.c:在函数‘hasActiveChildProcess’中:server.c:1478:1:警告:在有返回值......
  • CentOS中安装redis源码包
    下载地址#将redis压缩包上传到服务器/home/software,并解压tar-zxvfredis-6.0.6.tar.gz#安装gccyuminstallgcc-c++-y#查看版本gcc-v#进入解压目录#编译make#安装(默认安装到/usr/local/bin,不建议默认安装)#makeinstall#指定安装路径安装(......
  • 四、Work Queues(工作队列)
    一、轮训分发消息1、抽取工具类2、启动两个工作线程2.1两个工作线程(消费者)2.2生产者3、启动一个发送线程4、结果展示二、消息应答1、概念2、自动应答3、消息应答的方法4、Multiple的解释5、消息自动重新入队6、消息手动应答代码......
  • 基于FPGA的数字时钟设计与实现(含源码)
    随着数字电子技术的不断发展,基于FPGA(现场可编程门阵列)的数字时钟设计方案逐渐成为了一种流行的选择。本篇博客将详细介绍如何利用FPGA实现一个简单的数字时钟,涉及到分频器、数码管驱动、时分秒计数、三八译码器和扫描数码管等模块。1.系统设计概述在本设计中,我们将使用FPGA来实......
  • HashMap超详细源码解析
    原文链接:HashMap和HashSet源码解析1、HashMap概念HashMap实现了Map接口,是一种使用键值对存储数据的数据结构。HashMap允许null作为键和值。HashMap不保证元素的顺序,特别是不保证顺序恒定。HashMap是基于哈希表实现的数据结构,具有快速的插入、删除和查找操作。HashMap使用......
  • 如何开发互联网医院系统源码?互联网医院小程序开发全流程解析
    互联网医院系统源码的开发以及互联网医院小程序的设计是关键环节,本文将为您详细解析开发全流程。 一、需求分析与规划第一步,明确系统的功能模块。同时,规划系统的整体架构、技术栈,在这里需要想到系统的可扩展性和性能。二、数据库设计与建模建立互联网医院系统数据库是整个开发流程......
  • Vue源码学习(十七):实现computed计算属性
    好家伙,本章我们尝试实现computed属性 0.完整代码已开源https://github.com/Fattiger4399/analytic-vue.git 1.分析1.1computed的常见使用方法1.计算依赖数据:当某个数据发生变化时,computed属性可以自动更新,并返回计算结果。例如:<template><div><p>用户姓名:{{u......
  • linux源码趣读总结
    总结linux源码趣读花了半个月左右,看完了闪客的linux源码趣读。感觉之前上的操作系统原理课程只能给你一个模糊的印象,啊,有这个概念来着,有这个算法来着。比起从理论到实践的文字游戏,我还是更喜欢从实践讲理论的脚踏实地。从阅读linux-0.11源码,了解操作系统的构成。所谓的总结......