JS-----数据结构与算法(2)

news2024/9/29 5:26:26

目录

三. 栈结构

1.认识栈结构

2. 封装栈结构 

3. 应用

3-1 十进制转二进制

3-2 进制转换法

四. 队列

1.队列是什么?

2.队列的封装 

3. 队列的应用-击鼓传花

4. 双端队列

5.判断是否为回文


三. 栈结构

1.认识栈结构

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

特点:后进先出即Last in First Out(LIFO)。 

 函数调用栈

2. 封装栈结构 

class Stack {
    #items = []

    push(data) {
        this.#items.push(data)
    }

    pop() {
        return this.#items.pop()
    }

    peek() {
        return this.#items[this.#items.length - 1]

    }
    isEmpty() {
        return this.#items.length === 0
    }

    size() {
        return this.#items.length
    }

    clear() {
        this.#items = []
    }

    toString() {
        return this.#items.join("")
    }
}

3. 应用

商数是一个整数除法的运算结果,表示一个数被另一个数除后所得的整数部分。例如,当12被3除时,商数为4。余数是一个整数除法的运算结果,表示一个数被另一个数除后所得的余数。例如,当12被3除时,余数为0。

3-1 十进制转二进制

function convert(decNumber) {
    let remStack = new Stack()
    let number = decNumber
    let rem
    let string = ""
    while (number > 0) {
        rem = number % 2
        remStack.push(rem)
        // 向下取整
        number = Math.floor(number / 2)
    }
    while (!remStack.isEmpty()) {
        string += remStack.pop()
    }

    return string
}
console.log(convert(50));

3-2 进制转换法

function convert(decNumber, base) {
    let remStack = new Stack()
    let number = decNumber
    let rem
    let string = ""
    let baseStr = "0123456789ABCDEF"
    while (number > 0) {
        rem = number % base
        remStack.push(rem)
        number = Math.floor(number / base)
    }

    while (!remStack.isEmpty()) {
        string += baseStr[remStack.pop()]
    }

    return string
}
console.log(convert(500, 16));

四. 队列

1.队列是什么?

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。

2.队列的封装 

class Queue {
    #items = {}
    #count = 0//记录队列尾
    #lowCount = 0 //记录队列头 

    enqueue(data) {

        this.#items[this.#count] = data
        this.#count++
    }

    dequeue() {
        if (this.isEmpty()) {
            return undefined
        }
        let res = this.#items[this.#lowCount]
        delete this.#items[this.#lowCount]
        this.#lowCount++
        return res
    }
    isEmpty() {
        return this.size() === 0
    }

    size() {
        return this.#count - this.#lowCount
    }
    clear() {
        this.#items = {}
        this.#count = 0;
        this.#lowCount = 0
    }
    front() {
        return this.#items[this.#lowCount]
    }
    toString() {
        let str = ""
        for (let i = this.#lowCount; i < this.#count; i++) {
            str += `${this.#items[i]} `
        }
        return str
    }
}

3. 队列的应用-击鼓传花

  1. 击鼓传花的故事情境:类似于一个朋友圈或班级中的游戏,一群朋友或同学围成一个圆圈,开始传递一朵花。当音乐开始时,花会从一个人传递到另一个人,当音乐停止时,持有花的人将被淘汰。这个过程会不断重复,直到只剩下最后一个人。

  2. 实现思路:使用队列数据结构来模拟人围成的圆圈,将人按顺序排列,然后通过不断循环传递花的方式来模拟击鼓传花的过程。当音乐停止时,从队列或链表中移除当前持有花的人,并将花传递给下一个人,然后继续播放音乐,直到最后只剩下一个人。

function game(list, num) {
    // 1. 创建一个队列结构
    let queue = new Queue()
    // 2.将所有人依次加入到队列中
    for (let i = 0; i < list.length; i++) {
        queue.enqueue(list[i])
    }

    while (queue.size() > 1) {
        // 3.开始数数,不是num的时候,重新加入到队列的末尾
        for (let i = 0; i < num; i++) {
            queue.enqueue(queue.dequeue())
        }
        //4.删除队列头
        console.log(queue.dequeue(), "淘汰了")
    }
    // 5.获胜者
    return {
        winner: queue.dequeue()
    }
}

let winner = game(["张三", "李四", "王五", "丽萨", "韩梅梅"], 7)
console.log(winner);

4. 双端队列

class DeQueue {
    #items = {}
    #lowCount = 0//记录队列头(记录删除的个数)
    #count = 0//记录队列尾(记录追加的个数)
    // 从队列头删除
    removeFront() {
        if (this.isEmpty()) {
            return undefined
        }
        let res = this.#items[this.#lowCount]
        delete this.#items[this.#lowCount]
        this.#lowCount++
        return res
    }
    // 从对列头添加
    addFront(data) {
        // 如果为空
        if (this.isEmpty()) {
            this.addBack(data)
        } else {
            // 代表如果删除过元素
            if (this.#lowCount > 0) {
                this.#lowCount --
                this.#items[this.#lowCount] = data
            } else {
                // 没有删除过元素 lowCount===0
                for (let i = this.#count; i > 0; i--) {
                    // 假设队列中有一个元素{0:1}; this.#count=1; 下面这步骤:1(undefined) = {0:1} 
                    this.#items[i] = this.#items[i - 1]

                }
                // 赋值后 {0:1,1:1} 所有数据往前挪动一位 队列头插入
                this.#items[0] = data
                // 长度增长
                this.#count++

            }
        }
    }
    // 查找对头元素
    peekFront() {
        return this.#items[this.#lowCount]
    }
    // 从队尾加入
    addBack(data) {
        this.#items[this.#count] = data
        this.#count++
    }

    // 从对尾删除
    removeBack() {
        if (this.isEmpty()) {
            return undefined
        }
        this.#count--
        let res = this.#items[this.#count]
        delete this.#items[this.#count]
        return res
    }
    // 查找队尾元素
    peekBack() {
        return this.#items[this.#count - 1]
    }

    isEmpty() {
        return this.size() === 0
    }

    size() {
        return this.#count - this.#lowCount
    }

    clear() {
        this.#items = {}
        this.#count = 0
        this.#lowCount = 0
    }

    toString() {
        let str = ""
        for (let i = this.#lowCount; i < this.#count; i++) {
            str += `${this.#items[i]} `
        }
        return str
    }
}

5.判断是否为回文

function test(params) {
    const lowStr = params.toLocaleLowerCase().split(' ').join('')
    let dequeue = new DeQueue()
    for (let index = 0; index < lowStr.length; index++) {
        dequeue.addBack(lowStr[index])
    }
    let isEqual = true

    while (dequeue.size() > 1) {
        if (dequeue.removeFront() != dequeue.removeBack()) {
            isEqual = false
            break;

        }
    }
    return isEqual
}

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

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

相关文章

【计算机视觉中的 GAN 】 - 生成学习简介(1)

一、说明 在阅读本文之前&#xff0c;强烈建议先阅读预备知识&#xff0c;否则缺乏必要的推理基础。本文是相同理论GAN原理的具体化范例&#xff0c;阅读后有两个好处&#xff1a;1 巩固了已经建立的GAN基本概念 2 对具体应用的过程和套路进行常识学习&#xff0c;这种练习题一…

热备份路由协议原理

热备份路由协议原理 HSRP协议/VRRP协议热备份协议 热备份协议&#xff08;Hot Standby Protocol&#xff09; 是一种基于冗余设计的协议&#xff0c;用于提高网络的可靠性和冗余性。它允许多个设备共享同一个IP地址&#xff0c;其中一个设备被选为主设备&#xff0c;其他设备…

掌握Python的X篇_16_list的切片、len和in操作

接上篇掌握Python的X篇_15_list容器的基本使用&#xff0c;本篇进行进一步的介绍。 文章目录 1. list的索引下标可以是负数2. 切片&#xff08;slice&#xff09;2.1 切片基础知识2.2 如何“取到尽头”2.3 按照步长取元素2.4 逆序取值 3. len函数获取lis的元素个数4. in操作符…

Git 版本管理使用-介绍-示例

文章目录 Git是一种版本控制工具&#xff0c;它可以帮助程序员组织和管理代码的变更历史Git的使用方式&#xff1a;常见命令安装Git软件第一次上传分支删除分支 Git是一种版本控制工具&#xff0c;它可以帮助程序员组织和管理代码的变更历史 以下是Git的基本概念和使用方式&am…

AI 绘画Stable Diffusion 研究(二)sd模型ControlNet1.1 介绍与安装

部署包作者:秋葉aaaki 免责声明: 本安装包及启动器免费提供 无任何盈利目的 大家好&#xff0c;我是风雨无阻。 众所周知&#xff0c;StableDiffusion 是非常强大的AI绘图工具&#xff0c;需要详细了解StableDiffusion的朋友&#xff0c;可查看我之前的这篇文章&#xff1a; …

Qt6.5.2+WebRTC学习笔记(十三)开发环境搭建(macOS13.5)

前言 在ubuntu和win10开发测试一段时间了&#xff0c;但总在存在平台特性的问题&#xff0c;所以准备将程序移植到macOS上测试&#xff0c;同步进行三个主要桌面系统开发&#xff0c;本教程记录下环境搭建过程 一、准备 1.操作系统macOS13.5 64位 x86架构&#xff08;建议系…

tinkerCAD案例:22. Backpack Zipper Pull 背包拉链头

tinkerCAD案例&#xff1a;21. Custom Stamp 定制印章 原文 tinkerCAD案例&#xff1a;22. Backpack Zipper Pull 背包拉链头 Lesson Overview: 课程概述&#xff1a; Now we’re going to make a zipper pull! 现在我们要做一个拉链头&#xff01; Your backpack, howev…

【TypeScript】TS入门级基础学习(一)

【TypeScript】TS入门级基础学习&#xff08;一&#xff09; 一、前言 TypeScript 是一种用于应用程序规模的 JavaScript 语言。 TypeScript 向 JavaScript 添加了可选类型&#xff0c;支持用于任何浏览器、任何主机、任何操作系统的大规模 JavaScript 应用程序的工具。 Type…

【简历完善】- SLAM - 第一篇:卡尔曼滤波的学习

场景&#xff1a;晚上你需要从自己的卧室去上厕所&#xff0c;你知道家里的布局&#xff0c;了解自己的步长&#xff0c;但是没有灯。你如何才能走到厕所呢&#xff1f; 一些术语 “预测” “估计”。下面所说的预测和估计就是一回事。不同博客里面这两个词语大概意思也是一…

如何⾃定义⼀个SpringBoot Srarter

⾃定义⼀个SpringBoot Srarter 1、创建⼀个项⽬&#xff0c;命名为 demo-springboot-starter&#xff0c;引⼊SpringBoot相关依赖 2、编写配置⽂件 定义属性配置的前缀 3、⾃动装配 创建⾃动配置类HelloPropertiesConfigure 4、配置⾃动类 在 /resources/META-INF/spri…

ROS 基础知识汇总

How to learn ROS ROS for Beginners: How to Learn ROS - The Construct ROSwiki 界面介绍 ROS/Tutorials/NavigatingTheWiki - ROS Wiki ROS要学会哪些&#xff1f;如何学习Ros&#xff1f; - 知乎 setup.bash 的作用 ROS中的setup.bash_泠山的博客-CSDN博客 包的层级架构 …

ChatGPT长文本对话输入方法

ChatGPT PROMPTs Splitter 是一个开源工具&#xff0c;旨在帮助你将大量上下文数据分成更小的块发送到 ChatGPT 的提示&#xff0c;并根据如何处理所有块接收到 ChatGPT&#xff08;或其他具有字符限制的语言模型&#xff09;的方法。 推荐&#xff1a;用 NSDT设计器 快速搭建可…

如何搭建并部署抖音SEO源代码?

搭建并部署抖音SEO源代码&#xff0c;需要以下步骤&#xff1a; 购买服务器&#xff1a;在云服务商或者VPS提供商购买一台服务器&#xff0c;选择Linux系统。 安装LAMP/LEMP环境&#xff1a;LAMP是指Linux Apache MySQL PHP&#xff0c;LEMP是指Linux Nginx MySQL PHP。…

卷积的意义及其应用

卷积的意义及其应用 卷积的定义 我们将形如 ∫ − ∞ ∞ f ( τ ) g ( x − τ ) d τ \int^\infty_{-\infty} f(τ)g(x-τ)dτ ∫−∞∞​f(τ)g(x−τ)dτ 的式子称之为f&#xff08;x&#xff09;与g&#xff08;x&#xff09;的卷积记为 h ( x ) ( f ∗ g ) ( x ) h(x…

js开发技巧

1. 初始化数组 如果想要初始化一个指定长度的一维数组&#xff0c;并指定默认值&#xff0c;可以这样&#xff1a; const array Array(6).fill(); // [, , , , , ] 如果想要初始化一个指定长度的二维数组&#xff0c;并指定默认值&#xff0c;可以这样&#xff1a; const…

【尚硅谷】第01章:随堂复习与企业真题(Java语言概述)

来源&#xff1a;尚硅谷Java零基础全套视频教程(宋红康2023版&#xff0c;java入门自学必备) 基本都是宋老师发的资料里面的内容&#xff0c;只不过补充几个资料里没直接给出答案的问题的答案。 不想安装markdown笔记的app所以干脆在这里发一遍。 第01章&#xff1a;随堂复习…

电路原理分析1

d2的作用是提供一个1.25v的电平 r3、r4的作用都是限流 c1是滤波 运放的4、8脚是常规的外围 这个运放是一个运算放大电路 具体计算是这样的&#xff1a; 按照虚短原则&#xff0c;输入的信号Uinu1,输出的信号Uoutu3 按照虚断原则&#xff0c;i1i2i5i5 u1/r2i1i5&#xff…

windows使用多账户Git,多远程仓库版本管理

1 清除全局配置 git config --global --list // 看一下是否配置过user.name 和 user.email git config --global --unset user.name // 清除全局用户名 git config --global --unset user.email // 清除全局邮箱 2 本地仓库&#xff0c;每个远程对应的本地仓库目录下执行 $…

Redis缓存击穿问题以及解决方案

Redis缓存击穿问题以及解决方案 前言一、什么是Redis缓存击穿二、解决方案1.使用锁来解决使用锁的流程&#xff1a;核心思路&#xff1a;思路流程图&#xff1a;操作的锁的代码&#xff1a;业务的实现&#xff1a; 2.逻辑过期来解决思路分析&#xff1a;解决流程&#xff1a;业…

YOLOv5改进系列(17)——更换IoU之MPDIoU(ELSEVIER 2023|超越WIoU、EIoU等|实测涨点)

【YOLOv5改进系列】前期回顾: YOLOv5改进系列(0)——重要性能指标与训练结果评价及分析 YOLOv5改进系列(1)——添加SE注意力机制