• 【js】-【数组、栈、队列、链表基础】-笔记


    声明:本笔记是根据掘金小册总结的,如果要学习更多细节,请移步https://juejin.cn/book/6844733800300150797

    1 数组

    1.1 一维创建

    const arr = []
    const arr = new Array()
    
    • 1
    • 2

    指定长度

    const arr = new Array(7)
    
    • 1

    创建一个长度确定、同时每一个元素的值也都确定的数组

    const arr = (new Array(7)).fill(1)
    
    • 1

    1.2 一维遍历

    1. for 循环
    // 获取数组的长度
    const len = arr.length
    for(let i=0;i<len;i++) {
        // 输出数组的元素值,输出当前索引
        console.log(arr[i], i)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. forEach 方法
    arr.forEach((item, index)=> {
        // 输出数组的元素值,输出当前索引
        console.log(item, index)
    })
    
    • 1
    • 2
    • 3
    • 4
    1. map 方法

    在遍历的基础上“再加工”

    const newArr = arr.map((item, index)=> {
        // 输出数组的元素值,输出当前索引
        console.log(item, index)
        // 在当前元素值的基础上加1
        return item+1
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    map来返回了一个全新的数组,数组中每个元素的值都是在其现有元素值的基础上+1后的结果

    1.3 二维数组

    初始化一个二维数组

    const len = arr.length
    for(let i=0;i<len;i++) {
        // 将数组的每一个坑位初始化为数组
        arr[i] = []
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.4 二维数组遍历

    # 缓存外部数组的长度
    const outerLen = arr.length
    for(let i=0;i<outerLen;i++) {
        #  缓存内部数组的长度
        const innerLen = arr[i].length
        for(let j=0;j<innerLen;j++) {
           # 输出数组的值,输出数组的索引`const arr = [1,2]
    arr.push(3) // [1,2,3]`
            console.log(arr[i][j],i,j)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2 数组增加与删除方法

    2.1 数组中增加元素

    1. unshift 方法-添加元素到数组的头部
    const arr = [1,2]
    arr.unshift(0) # [0,1,2]
    
    • 1
    • 2
    1. push 方法-添加元素到数组的尾部
    const arr = [1,2]
    arr.push(3) # [1,2,3]
    
    • 1
    • 2
    1. splice 方法-添加元素到数组的任何位置
    const arr = [1,2] 
    arr.splice(1,0,3) # [1,3,2]
    
    • 1
    • 2
    第一个入参是起始的索引值,第二个入参表示从起始索引开始需要删除的元素个数,第三个参数是传入值
    
    • 1

    2.2 数组中删除元素

    1. shift 方法-删除数组头部的元素
    const arr = [1,2,3]
    arr.shift() # [2,3]
    
    • 1
    • 2
    1. pop 方法-删除数组尾部的元素
    const arr = [1,2,3]
    arr.pop() # [1,2]
    
    • 1
    • 2
    1. splice 方法-删除数组任意位置的元素
    const arr = [1,2,3]
    arr.splice(1,1) # [1, 3]
    
    • 1
    • 2

    3 栈、队列

    栈和队列的实现一般都要依赖于数组
    两者的区别在于,它们各自对数组的增删操作有着不一样的限制。

    3.1 栈

    只允许从尾部添加元素
    只允许从尾部取出元素

    // 初始状态,栈空
    const stack = []  
    // 入栈过程
    stack.push('东北大板')
    stack.push('可爱多')
    stack.push('巧乐兹')
    stack.push('冰工厂')
    stack.push('光明奶砖')
    
    // 出栈过程,栈不为空时才执行
    while(stack.length) {
        // 单纯访问栈顶元素(不出栈)
        const top = stack[stack.length-1]
        console.log('现在取出的冰淇淋是', top)  
        // 将栈顶元素出栈
        stack.pop()
    }
    
    // 栈空
    stack // []
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.2队列

    只用 push 和 shift 完成增删的“数组”

    const queue = []  
    queue.push('小册一姐')
    queue.push('小册二姐')
    queue.push('小册三姐')  
      
    while(queue.length) {
        // 单纯访问队头元素(不出队)
        const top = queue[0]
        console.log(top,'取餐')
        // 将队头元素出队
        queue.shift()
    }
    
    // 队空
    queue // []
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    4 链表

    链表中,数据单位的名称叫做“结点”,而结点和结点的分布,在内存中可以是离散的。
    要想访问链表中的任何一个元素,我们都得从起点结点开始,逐个访问 next,一直访问到目标结点为止。为了确保起点结点是可抵达的,我们有时还会设定一个 head 指针来专门指向链表的开始位置:在这里插入图片描述

    1. 创建链表结点,需要一个构造函数:
    function ListNode(val) {
        this.val = val;
        this.next = null;
    }
    
    • 1
    • 2
    • 3
    • 4
    1. 使用构造函数创建结点
    const node = new ListNode(1)  
    node.next = new ListNode(2)
    
    • 1
    • 2

    数据域值为1,next 结点数据域值为2
    在这里插入图片描述
    3. 任意两结点间插入一个新结点

    我们需要变更的是前驱结点目标结点的 next 指针指向
    在这里插入图片描述

    # 如果目标结点本来不存在,那么记得手动创建
    const node3 = new ListNode(3)     
    
    # 把node3的 next 指针指向 node2(即 node1.next)
    node3.next = node1.next
    
    # 把node1的 next 指针指向 node3
    node1.next = node3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 链表元素的删除

    直接让它的前驱结点 node1 的 next 指针跳过它、指向 node3 的后继在这里插入图片描述

    node1.next = node3.next 
    
    • 1

    可以只使用一个指针,这个指针用来定位目标结点的前驱结点。

    // 利用 node1 可以定位到 node3
    const target = node1.next  
    node1.next = target.next
    
    • 1
    • 2
    • 3

    相对于数组来说,链表有一个明显的优点,就是添加和删除元素都不需要挪动多余的元素

    在链表中,只要明确了要插入/删除的目标位置,增删操作的复杂度是常数级别的复杂度,表示为 O(1)。

    但是链表也有一个弊端:当我们试图读取某一个特定(第i个)的链表结点时,必须遍历整个链表来查找它,表示为 O(n)。
    但在数组中,我们直接访问索引、可以做到一步到位,这个操作的复杂度会被降级为常数级别O(1)

    链表的插入/删除效率较高,而访问效率较低;数组的访问效率较高,而插入效率较低

  • 相关阅读:
    插件器件小的引脚孔,制造过程中可能存在的一些问题
    Taurus.MVC 微服务框架 入门开发教程:项目部署:5、微服务应用程序发布到Docker部署(下)。
    TS中的info用法
    Python Matplotlib库:基本绘图补充
    Airtest新手升级:一个相对完整的纯.py脚本是怎样子的
    ST-Link的LED指示灯说明
    第151篇 Solidity Example(1)
    2022杭电多校九 1008-Shortest Path in GCD Graph(质因子+容斥)
    网络安全(6)
    ArrayList_扩容原则
  • 原文地址:https://blog.csdn.net/weixin_40852935/article/details/125392807