JavaScript数据结构之链表

755 阅读1分钟

链表介绍

除了数组之外,链表也是一种常见的数据结构类型

常见组织形式

  1. 链表中的每个节点至少包含两个部分:数据域 与 指针域
  2. 链表中的每个节点,通过指针域的值,形成一个线性结构
  3. 查找节点O(n),插入节点 O(1), 删除节点O(1)
  4. 不适合快速的定位数据,适合动态的插入和删除数据的应用

经典应用场景

  1. 操作系统内的动态内存分配(内存碎片维护为一个链表结构)
  2. LRU缓存淘汰算法

实现一个链表(单向)

基于链表的特性,我们要实现一个基础版本的链表数据结构。

功能如下

  • 创建链表类
  • 创建链表方法类
  • 创建链表节点方法
  • 插入链表节点
  • 删除链表节点
  • 查找链表节点

代码

创建链表类

class ListNodeItem {
    value: any;
    next: ListNodeItem | null;

    constructor(value?: any) {
        this.value = value;
        this.next = null;
    }
}

创建链表方法类

class ListNode {
    head: ListNodeItem;
    end: ListNodeItem;

    constructor(value?: any) {
        this.head = new ListNodeItem(value);
        this.end = this.head;
    }

    // 增加一个链表数据
    add = (value: any) => {
        this.end.next = new ListNodeItem(value);
        this.end = this.end.next;
    };

    // 查找
    find = (item: any): ListNodeItem | null => {
        let currentNode: ListNodeItem | null = this.head;
        while (currentNode?.value !== item && currentNode) {
            currentNode = currentNode.next;
        }
        return currentNode;
    };

    findPrevious = (item: any): ListNodeItem | null => {
        let prevNode: ListNodeItem | null = this.head;
        while (prevNode?.next && prevNode?.next.value !== item) {
            prevNode = prevNode.next;
        }
        return prevNode;
    };

    // 删除
    remove = (item: any) => {
        let currentNode = this.findPrevious(item);
        if (currentNode?.next) {
            currentNode.next = currentNode.next.next;
            if (!currentNode.next) this.end = currentNode;
        }
    };

    // 插入
    insert = (newItem: any, item: any) => {
        const currentNode = this.find(item);
        const newNode = new ListNodeItem(newItem);
        if (currentNode) {
            newNode.next = currentNode.next;
            currentNode.next = newNode;
            if (!newNode.next) this.end = newNode;
        }
    };
    
    // 打印输出方法
    print = () => {
        let currNode: ListNodeItem | null = this.head;
        while (currNode && currNode.value) {
            console.log(currNode.value);
            currNode = currNode.next;
        }
    };
}

链表刷题

链表的访问

leetcode-141.环形链表

leetcode-160.相交链表

链表的反转

leetcode-206.链表的反转

链表的删除

暂无