如何在javascript中实现deque数据结构?

2024-05-04

我正在用 javascript 学习数据结构

我现在的重点是如何实现双端队列?

编辑:从下面的评论中我得到了有关如何实施的有用指示deque based array。有没有一个具体实施的方向deque based object使用类?

我明白了我需要的一些要点:

  • 添加前()
  • 删除前面()
  • peekFront()

  • 添加返回()
  • 移除返回()
  • 回看()

但我对某些点感到困惑:

  • 我需要多少指针? 至少我知道queue我需要两个(头尾)指针,但不确定是否需要更多deque

  • 在这种情况下,javascript 中哪种数据类型方便作为基础?我在 youtube 上看到一些导师谈论圆形数组,例如我在 JS 中不知道的。

edite2:

我正在关注一本书,名为:学习javascript数据结构与算法第三版

在本书的第五章中,作者开始实现仅基于对象和一些变量的双端队列

但我不明白他是如何做到这一点的,因为代码已加密,但我仍然可以访问他的文件并测试他的方法github 存储库 https://github.com/PacktPublishing/Learning-JavaScript-Data-Structures-and-Algorithms-Third-Edition/tree/master/LearningJavaScriptDataStructuresandAlgorithmsThirdEdition_Code/examples/chapter05

我可以说@trincot 的回答非常接近书籍作者的方法

but when I compare the results I get this [1 = author - 2 = @trincot] : enter image description here

根据本书索引取约链表出现在第六章,所以我没想到他的解决方案会基于他之前没有提到的东西

如果我错过任何一点,我将不胜感激地告诉我......谢谢


正如评论和维基百科中所述mentions https://en.wikipedia.org/wiki/Double-ended_queue#Language_support--,JavaScript 通过其 Array 类/原型对双端队列操作提供本机支持:push、pop、shift、unshift。然而,这并不能提供最佳的时间效率,随着数据集的增大,这一点变得很重要。

如果您需要较大数据集的良好性能,您将需要编写自己的实现。您可以使用双向链表,其中只需要两个“指针”。应该说,在 JavaScript 中我们真正谈论的不是指针,而是对象。获取对象作为值的变量或属性实际上是参考在 JavaScript 中。

或者,您可以选择圆形阵列。由于在 JavaScript 标准数组中不能保证是连续数组(例如 C 中的情况),因此您实际上不需要为此使用数组实例。一个普通的对象(或地图)就可以了。

所以这里有两种可能的实现:

双向链表

class Deque {
    constructor() {
        this.front = this.back = undefined;
    }
    addFront(value) {
        if (!this.front) this.front = this.back = { value };
        else this.front = this.front.next = { value, prev: this.front };
    }
    removeFront() {
        let value = this.peekFront();
        if (this.front === this.back) this.front = this.back = undefined;
        else (this.front = this.front.prev).next = undefined;
        return value;
    }
    peekFront() { 
        return this.front && this.front.value;
    }
    addBack(value) {
        if (!this.front) this.front = this.back = { value };
        else this.back = this.back.prev = { value, next: this.back };
    }
    removeBack() {
        let value = this.peekBack();
        if (this.front === this.back) this.front = this.back = undefined;
        else (this.back = this.back.next).back = undefined;
        return value;
    }
    peekBack() { 
        return this.back && this.back.value;
    }
}

// demo
let deque = new Deque;
console.log(deque.peekFront()); // undefined
deque.addFront(1);
console.log(deque.peekBack()); // 1
deque.addFront(2);
console.log(deque.removeBack()); // 1
deque.addFront(3);
deque.addFront(4);
console.log(deque.peekBack()); // 2
deque.addBack(5);
deque.addBack(6);
console.log(deque.peekBack()); // 6
console.log(deque.removeFront()); // 4
console.log(deque.removeFront()); // 3
console.log(deque.removeFront()); // 2
console.log(deque.removeFront()); // 5
console.log(deque.removeFront()); // 6
console.log(deque.removeFront()); // undefined

圆形“阵列”

class Deque {
    constructor() {
        this.data = {}; // Or Array, but that really does not add anything useful
        this.front = 0;
        this.back = 1;
        this.size = 0;
    }
    addFront(value) {
        if (this.size >= Number.MAX_SAFE_INTEGER) throw "Deque capacity overflow";
        this.size++;
        this.front = (this.front + 1) % Number.MAX_SAFE_INTEGER;
        this.data[this.front] = value;
    }
    removeFront()   {
        if (!this.size) return;
        let value = this.peekFront();
        this.size--;
        delete this.data[this.front];
        this.front = (this.front || Number.MAX_SAFE_INTEGER) - 1;
        return value;
    }
    peekFront()     { 
        if (this.size) return this.data[this.front];
    }
    addBack(value) {
        if (this.size >= Number.MAX_SAFE_INTEGER) throw "Deque capacity overflow";
        this.size++;
        this.back = (this.back || Number.MAX_SAFE_INTEGER) - 1;
        this.data[this.back] = value;
    }
    removeBack()   {
        if (!this.size) return;
        let value = this.peekBack();
        this.size--;
        delete this.data[this.back];
        this.back = (this.back + 1) % Number.MAX_SAFE_INTEGER;
        return value;
    }
    peekBack()     { 
        if (this.size) return this.data[this.back];
    }
}

// demo
let deque = new Deque;
console.log(deque.peekFront()); // undefined
deque.addFront(1);
console.log(deque.peekBack()); // 1
deque.addFront(2);
console.log(deque.removeBack()); // 1
deque.addFront(3);
deque.addFront(4);
console.log(deque.peekBack()); // 2
deque.addBack(5);
deque.addBack(6);
console.log(deque.peekBack()); // 6
console.log(deque.removeFront()); // 4
console.log(deque.removeFront()); // 3
console.log(deque.removeFront()); // 2
console.log(deque.removeFront()); // 5
console.log(deque.removeFront()); // 6
console.log(deque.removeFront()); // undefined

方法将返回undefined,当尝试从空双端队列中检索值时。

在我的测试中,随着数据集的增长,链表解决方案成为获胜者。对于较小的数据集大小,本机数组可能是最好的。但它也取决于双端队列元素所具有的引擎和数据类型:整数的结果与对象或字符串的结果不同。因此,我建议对您的实际数据和双端队列操作进行一些基准测试,以了解哪种实现最适合您的情况。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在javascript中实现deque数据结构? 的相关文章

  • ReferenceError:找不到变量:需要

    我在加载时遇到问题node modules到我的网页之一 我已经安装了 npm node js 并且我想使用require 函数在我的网站上初始化 Firebase 我不知道为什么 但它抛出引用错误 ReferenceError 找不到变量
  • 如何理解 Angular JS 中的控制台错误消息?有什么工具吗?

    我是 Angular JS 的新手 我的第一个问题是如何理解 Angular JS 中控制台的错误消息 我编写了这段用于匹配密码的代码片段 它在控制台上抛出错误 但它工作正常 它是有线的 我无法从这些控制台消息中理解任何内容 谁能指出我为什
  • 我可以从 HTTP 请求中找到无线接入点的 BSSID(MAC 地址)吗?

    假设有人在咖啡店里无线连接到互联网 并向 johnsveryownserver com 发送 HTTP 请求 服务器端 有什么方法可以确定我的MAC地址吗 无线接入点他们连接到什么 请注意 我对他们机器的 MAC 地址不感兴趣 如果我无法使
  • 如何使用键盘和鼠标控制相机 - Three.js

    我在 WEB GL 中有一个带有 Three js 的 3D 环境 并且我曾经使用 Orbitcontrols js http codepen io nireno pen cAoGI http codepen io nireno pen c
  • ElectronJS ReferenceError:导航器未定义

    我正在尝试在电子上制作自定义标题栏 但是当我启动我的应用程序时 我遇到了 ReferenceError 导航器未定义 问题 请帮忙 这是我的 main js 中的代码片段 My Codes https i stack imgur com c
  • 保存/导出Chrome的JavaScript控制台输入历史记录

    无论如何 我可以保存或导出 JavaScript 控制台的历史记录吗 input 控制台历史记录 在 Google Chrome 中 我不想保存输出或错误 因此将鼠标悬停在控制台框上 右键单击并选择Save as 不是解决方案 我不想每次都
  • 如何记录返回的事件发射器

    如何记录所发出的事件stream返回于MyFunc 与 JSDoc MyFunc description param Object opts description return Stream description function My
  • 如何改变HTML5视频的播放速度?

    如何更改 HTML5 中的视频播放速度 我查过视频标签的属性 https www w3schools com html html5 video asp在 w3school 但无法做到这一点 根据这个网站 http www chipwreck
  • 访问 TypeScript 数组的最后一个元素

    TypeScript 中有访问数组最后一个元素的符号吗 在 Ruby 中我可以说 array 1 有类似的东西吗 您可以通过索引访问数组元素 数组中最后一个元素的索引将是数组的长度 1 因为索引是从零开始的 这应该有效 var items
  • jQuery 选择器:为什么 $("#id").find("p") 比 $("#id p") 更快

    该页面的作者 http 24ways org 2011 your jquery now with less suck http 24ways org 2011 your jquery now with less suck断言 jQuery
  • 如何滚动到div内的元素?

    我有一个滚动的div我想在点击它时发生一个事件 它会强制执行此操作div滚动以查看内部元素 我写的JavasCript是这样的 document getElementById chr scrollIntoView true 但这会在滚动时滚
  • Flux + React.js - 操作中的回调是好还是坏?

    让我解释一下我最近遇到的问题 我有 React js Flux 驱动的应用程序 有一个列表显示文章数量 注意 应用程序中有多个不同的列表 和文章详情查看在里面 但每个列表只有一个 API 端点 它返回文章数组 为了显示我需要的详细信息fin
  • 如何将 Browserify 与外部依赖项一起使用?

    我正在尝试慢慢地将 Browserify 引入我的网站 但我不想重写所有 js 也不希望 jquery 和其他库的重复实例与我的 Browserify 版本捆绑在一起 如果我构建将 jquery 列为外部依赖项的模块 那么如何将其指向我的全
  • window.showModalDialog 的等效跨浏览器解决方案是什么?

    window showModalDialog 的等效跨浏览器解决方案有哪些 showModalDialog 在 IE 和 FF 3 中引入 我个人认为没有 但是有很多 UI 工具包提供了这样的功能 例如jQuery UI http jque
  • ng-model 和值组合不适用于输入文本框

    我有两个输入文本框 我需要组合在两个文本框中输入的值并将其显示在第三个文本框中 如果我只使用value在第三个文本框中 Box 1
  • 如何获取使用 .map 渲染的第一个元素的 ref?

    我需要在几行中显示视频 卡片 的缩略图 并重点关注第一个缩略图 我使用嵌套地图进行了显示 该代码基本上迭代视频数组并返回多行视频 我们如何关注第一个渲染的元素 我认为我们需要获得第一个要聚焦的元素的引用 但是我们如何在这里设置 ref 并在
  • 在javascript中动态生成行?

    我是 javascript 新手 我想在按下 Tab 时动态生成行 并希望获取在动态生成的行中输入的值 以便我可以在 servlet 代码中使用这些值 这是我的html
  • 如何在 SVG 元素上使用箭头标记?

    我需要在 d3 js 中创建一个箭头 但我找到的只是带有节点图的示例 我需要的是简单地制作一个从 A 点到 B 点的箭头 我尝试实现以下示例中的部分代码 http bl ocks org 1153292 http bl ocks org 1
  • 如何更改订阅值?使用 rxJS

    我正在创建一个计时器 需要你的帮助 我刚刚学习 Angular 和 rxJS 对此我有一些疑问 我正在创建一个具有启动 停止 暂停 重置功能的计时器 并且 btn Reset 必须将我的计时器 暂停 到 300 毫秒 怎么做 D 我的启动定
  • 在 javascript 中使用 xPath 解析具有默认命名空间的 XML

    我需要创建一个 XML xPath 解析器 所有解析都必须在客户端进行 使用 JavaScript 我创建了一个 javascript 来执行此操作 在默认名称空间发挥作用之前 一切看起来都正常 我根本无法查询具有默认命名空间的 XML 我

随机推荐