48 # 单向链表

上一节讲了可读流,在讲可写流之前得了解一下链表。

比如:并发往文件中写入数据

write("1");
write("2");
write("3");

每次写都会开个线程,上面的写入可能出现 123321213

node 中主线程是单线程,没有锁的概念。

怎么解决这种问题?

线性的数据结构

队列:比如宏任务微任务就是队列,从第一个开始取出来执行,先进先出

  • 入队:arr.push
  • 出队: arr.shift

栈结构:代码执行会销毁的顺序,就是一个栈型结构,先进后出

  • 入栈:arr.push
  • 出栈:arr.pop

链表:链表从头和尾取值性能高,也能存放数据,平均查询的复杂度是 O(n),基于链表可以实现队列的封装,没有数组的塌陷问题。

  • 单向链表:每个节点有 next 属性指向下一个,头指向第一个元素

在这里插入图片描述

  • 单向循环链表:最后一个元素指向头部

在这里插入图片描述

  • 双向链表:两个指针分别指向前一个和后一个

在这里插入图片描述

  • 双向循环链表:两个指针分别指向前一个和后一个,第一个的前一个指向尾,最后的后一个指向头

在这里插入图片描述

  • 环形链表:最后一个元素的 next 指向了其他的节点

在这里插入图片描述

简单的实现单向链表

class Node {
    
    
    constructor(element, next) {
    
    
        this.element = element;
        this.next = next;
    }
}

class LinkedList {
    
    
    constructor() {
    
    
        this.head = null; // 链表的头
        this.size = 0; // 链表长度
    }
    // 可以直接在尾部添加内容,或者根据索引添加
    add(index, element) {
    
    
        // 传入一个参数是需要设置一下 index, element
        if (arguments.length === 1) {
    
    
            // 在尾部添加,传入的 index 就当做是 element
            element = index;
            // 然后把 this.size 当做索引
            index = this.size;
        }
        // 处理越界可能
        if (index < 0 || index > this.size) throw new Error("越界");
        // 判断 index 是否为 0
        if (index === 0) {
    
    
            // 老的头
            let head = this.head;
            // 设置新头,将老的头变为当前节点的下一个
            this.head = new Node(element, head);
        } else {
    
    
            // 先找到当前索引的上一个
            let prevNode = this.getNode(index - 1);
            // 将当前上一个节点的 next 指向新的节点,新的节点的下一个指向上一个节点的 next
            prevNode.next = new Node(element, prevNode.next);
        }
        // 累加 size
        this.size++;
    }
    getNode(index) {
    
    
        // 从头开始找
        let current = this.head;
        // 不能向后找,找到索引的位置
        for (let i = 0; i < index; i++) {
    
    
            current = current.next;
        }
        return current;
    }
}

let ll = new LinkedList();
ll.add(0, 1);
ll.add(0, 2);
ll.add(3);
ll.add(1, 4);

console.dir(ll, {
    
     depth: 100 });

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/kaimo313/article/details/131536472
48